プロトコル
フィーダー、リレー、クライアントが相互運用するために話す必要がある内容です。リファレンスは Tally リポジトリの wire クレートです。リポジトリ内でプロトコルをエンコード・デコードする唯一のコードであり、すべてのバイナリがこれを使っています。整数はすべてビッグエンディアンです。
トランスポート
すべてのホップは TCP 上の Noise_IK_25519_ChaChaPoly_BLAKE2s です。各 Noise メッセージは 2 バイトの長さに続けて送られ、タグを含めて最大 65,535 バイトで、完全なレコードだけを運びます。
ID は 1 つの Ed25519 鍵です。Noise が認証する X25519 鍵はそこから導出され(libsodium の sk_to_curve25519)、イニシエーターの最初のハンドシェイクメッセージには、イニシエーターの 32 バイトの Ed25519 公開鍵が含まれます。レスポンダーはそれを、ハンドシェイクで証明された鍵と照合します。1 つの鍵が、どこでも 1 本のアンテナを表します。
プリアンブル
ハンドシェイクの前に、イニシエーターは平文で 16 バイトを送ります。これは Noise のプロローグでもあるため、1 バイトでも変わればハンドシェイクは失敗します。また、これによって将来ハンドシェイク自体を変更でき、リレーは鍵のローテーション中に新旧両方の鍵を保持できます。
バージョン
続いてイニシエーターは、対応するワイヤーバージョンの最小値と最大値、および自分の役割を載せた Hello を送ります。レスポンダーは、以後双方が使うバージョンを載せた Welcome、または理由と待機時間を載せた Goodbye で応答します。最初のバイトから Welcome までは最大 15 秒で、それ以降の各送信には 30 秒の期限があります。現時点でワイヤーバージョンは 1 だけです。
リレーは、これまでにフィーダーが出荷したすべてのワイヤーバージョンに、永久に応答します。インストール済みのフィーダーは更新されず、プロトコルのほかの部分はすべてこのルールを前提にしています。
レコード
レコードは、種別を表す 1 バイト、2 バイトの本体長、本体で構成されます。ワイヤーバージョン 1 が認識する種別は次のとおりです:
変更のルール
フィーダーは更新されないため、フィーダーを更新せずにプロトコルを変更するための次のルールがあります:
- 未知の種別はスキップされます。ただし、最上位ビット(0x80)で重要と示されている場合は、セッションを正常に終了します。したがって新しいレコードは、無視すると不都合が生じる場合を除き、重要とはしません。
- 本体には、読み手が知っているフィールドの後ろにバイトが続くことがあり、それらは無視されます。フィールドは末尾に追加する形で増やします。
- 読み手は、知らない列挙値を Other という値として保持し、エラーにはしません。
- 署名付きの形式は、どのフォーマットバージョンでも同じプレフィックスを保ち、それより前のすべてに対する署名で終わります。そのため、リレーはそれ以外の部分を読めないフォーマットでも、検証、ルーティング、重複除去ができます。
- 観測データのフォーマットは、1090 MHz では BEAST 自身のタイプバイトです。978 MHz UAT には新しい値を割り当てるため新しいレコードは不要で、リレーは知らないフォーマットもそのまま転送します。
署名付きバッチ
バッチは、1 台の受信機の約 1 秒分の受信データです。フォーマット 1 の構成は次のとおりです:
観測データのフォーマット:1 は Mode A/C(2 バイト)、2 は Mode-S short(7)、3 は Mode-S long(14)、D は 978 MHz UAT のダウンリンク、U は UAT の地上アップリンクで、それぞれ ASCII 文字として書き込みます。
署名の対象は、ASCII テキストの tally batch、ゼロバイト 1 つ、そして署名より前のバッチの全バイトです。リレー自身の重複除去済みバッチは代わりに tally relay batch で署名するため、一方が他方になりすますことはできません。
バッチの ID は、署名を含む全バイトの BLAKE2s-256 ハッシュです。リレーはこれを使って重複を除去し、次のバッチの前バッチフィールドがこれを指します。
先頭の 49 バイト(フォーマット、鍵、ブート ID、シーケンス)は将来のどのフォーマットでも位置を変えず、署名は常に最後に置かれます。
MLAT に渡す前にカウンターを補正することは、誰であっても決してありません。リレーの MLAT が位置を解くには生のカウンターが必要だからです。