これは参考用の翻訳です。正式な基準は英語版であり、内容が食い違う場合は英語版が優先されます。 英語版を読む

セキュリティモデル

Label 309 の検証者が信頼するもの、信頼しないものを整理します。単独で検証可能という不変条件、封緘済みレコードによる存在証明のプライバシー保証、すべての実装が守らなければならない規範的な暗号規則、そしてワイヤーフォーマットが抱える既知の限界をまとめます。

Label 309 のセキュリティは、たった一つの考え方の上に成り立っています。証明とは、それに依拠する側が自分で確かめるものだ、という考え方です。検証者が信頼するのは、公開された Cardano チェーンと、コンテンツに関する主張を確かめる場合に限り手元のバイト列だけです。それ以外は一切信頼しません。発行者も、ドメインも、サーバーも、たまたまトランザクションを読み取った先のゲートウェイ運営者も、信頼の対象には含みません。このページに記載するすべての保証は、この立場から導かれるか、その境界を示すか、あるいはその範囲の外に残るリスクを明示するか、のいずれかです。

このページは、標準そのものに対する脅威モデルです。準拠した検証者が前提とする信頼モデル、署名のない封緘済みレコードによる存在証明(Proof of Existence, PoE)のプライバシー特性、すべての実装が守らなければならない(MUST)暗号上の義務、そしてワイヤーフォーマットでは克服できない、また克服しようもない限界を扱います。個々の運用環境におけるセキュリティ運用については述べません。正しく実装した者すべてに対してフォーマットが何を保証するのかを述べます。

信頼モデル

Label 309 の証明を確かめる側が問うているのは、ごく限られた一点です。このバイト列は、あるブロックの時刻以前に存在していたのか。そして、その判断は Cardano 以外の誰かが行儀よくふるまうことに左右されるのか。 標準は、この後半の問いに対する答えが常に「いいえ」になるよう組み立てられています。どの段階にも、発行者が支配する仲介者は存在しません。検証者が参照するチェーンゲートウェイとストレージゲートウェイは、信頼されないデータソースであり、可能な箇所では暗号学的に検証され、取り込みと確定については突き合わせで確かめられます。

検証者が信頼するもの。

  • 公開された Cardano チェーン。 トランザクション、ラベル 309 のもとに置かれたそのメタデータ、そしてブロック時刻は、すべての Cardano ノードに複製された事実です。検証者はこれらを自分で選んだゲートウェイ経由で読み取り、複数のゲートウェイで突き合わせることもできます。
  • コンテンツに関する主張を確かめる場合の、そのコンテンツのバイト列。 レコード内のダイジェストは、特定のバイト列にコミットしています。そのバイト列を手にした検証者は、ハッシュ値を再計算して照合します。バイト列が一致するという他人の言葉を鵜呑みにすることはありません。

検証者が信頼しないもの。

  • 発行者。 Label 309 には issuer フィールドがありません。どのウォレットでも、どんなレコードでも発行できます。レコードが有効かどうかは、誰が提出したかとは無関係です。検証者が「この発行者は信頼できるか」と問うことは決してなく、その問い自体がこのモデルには居場所を持ちません。はじめにで述べる発行者非依存の不変条件を参照してください。
  • サーバーやドメイン。 検証のどの段階でも、発行者が運用するサービスに接続することはありません。参照すべき正規のレジストリも、状態を問い合わせるエンドポイントも、鍵を照合するための権威あるアイデンティティ機関も存在しません。
  • ゲートウェイ運営者。 検証者が読み取りに使う Cardano、Arweave、IPFS の各ゲートウェイは、互いに置き換え可能であり、返ってきた内容はコンテンツとして検証されます(後述)。ゲートウェイは伝送路にすぎず、信頼の起点ではありません。

単独で検証できることが、セキュリティの核心です

Label 309 の証明は、それを生み出したすべての関係者、すなわち発行者も、そのサーバーも、その会社も、姿を消してもなお検証できなければなりません。トランザクション参照と、公開された Cardano ゲートウェイと、そして(コンテンツに関する主張であれば)バイト列さえあれば、準拠したどの実装でも、公開されたチェーンだけから同じ判定にたどり着きます。検証経路が、特定の運営者の協力をひそかに必要としているなら、その経路は準拠していません。

ゲートウェイが信頼の起点にならない理由

検証者は、同じトランザクションをどの Cardano ゲートウェイ経由でも読み取れますし、同じコンテンツをどの Arweave または IPFS ゲートウェイ経由でも読み取れます。これらのいずれも、正直なデータを返すという前提では信頼されていません。返ってくる内容は、独立して確かめられるからです。

  • ゲートウェイは、有効な署名を持つレコードを偽造できません。署名者の秘密鍵を持っていませんし、検証者は署名対象のバイト列を自分で再計算して確かめます。署名を参照してください。
  • ゲートウェイは、コンテンツアドレス指定の URI のもとにあるコンテンツを、検知されずに差し替えることはできません。ipfs:// の CID は、検証者が取得したバイト列から再計算するマルチハッシュであり、ar:// のトランザクション ID は Arweave のコンセンサスのもとでデータにコミットしています。準拠したアイテムでは、オンチェーンの hashes マップが、取得時に再計算される、平文への二つ目の独立した結び付きとなります。
  • トランザクションを隠すゲートウェイや、どれだけ深く埋まっているかを偽って報告するゲートウェイは、偽造ではなくサービス拒否の形をとります。複数のゲートウェイ経由で読み取り、食い違いがあれば処理を中止する検証者にとって、「一つの不誠実なゲートウェイ」という問題は、「自分が選んだすべてのゲートウェイにまたがる共謀」へと姿を変えます。そして、その選択は検証者自身が握っています。

ブロックの深さ、すなわちレコードを確定したものとして扱うまでに検証者が要求する確認数は、Label 309 が定める値ではなく、検証者のポリシーです。標準は具体的な深さの数値を一切固定しません。依拠する側が、自らのリスク許容度に合わせてしきい値を決めます。検証を参照してください。

封緘済みレコードによる存在証明のプライバシー特性

封緘済みレコードによる存在証明は、平文を秘密に保ちながら、そのタイムスタンプをチェーン上に固定します。機密性に加えて、この構成は、メッセージについてはできるだけ少ない情報しかチェーン上に漏らさず、その宛先については何も漏らさないように設計されています。これらはワイヤーフォーマットの保証です。特定の運用環境の性質ではなくバイト列そのものの性質なので、正しく実装したものであればどの実装でも成り立ちます。

署名のない封緘済みレコードにおける送信者の匿名性

署名のない封緘済みレコード、すなわち enc を持ち sigs持たないレコードは、送信者のアイデンティティをチェーン上で開示してはならない(MUST NOT)。そのワイヤー上のバイト列は、送信者の長期鍵とは独立でなければならない(MUST)。

これは構造として保証されます。

  • ワイヤー上に署名者の鍵が乗らない。 送信者のアイデンティティ鍵がチェーンに届くのは、sigs のエントリを通じた場合だけです。sigs を持たないレコードには、送信者側のバイトが一つも含まれません。著作者性はオプトインであり、匿名性が既定です。署名のないレコードに、送信者の長期 X25519 鍵と Ed25519 鍵が現れることはありません。
  • スロットごとの新しいカプセル化。 各受信者スロットは、封緘の時点で新しく生成された、レコードごと・スロットごとの KEM 材料を保持します。x25519 の経路では slot.epk の X25519 エフェメラル公開鍵、mlkem768x25519 の経路では slot.kem_ct の X-Wing 暗号文です。これは送信者の長期鍵とは無関係であり、複数のレコードを同一の作成者に結び付ける手がかりは何も明かしません。
  • シャッフルされたスロット。 スロットの配列は、発行前に CSPRNG でシャッフルされます。そのため「主たる受信者が先頭にいる」といった位置の並びが手がかりになることはありません。

あとからレコードに署名する発行者は、その レコードに限ってアイデンティティ鍵を開示するだけです。その鍵は、それ以前の署名のないレコードには現れませんし、以前のレコードのスロットごとの KEM 材料から作成者をたどり直す操作も存在しません。アイデンティティの X25519 鍵と Ed25519 鍵は、マスターシードから 異なる HKDF コンテキスト文字列によって導出され、しかも Ed25519 公開鍵から X25519 公開鍵を導出したり照合したりすることはできないため、あるレコードに署名しても、署名のないレコード群と結び付くことは決してありません。著作者性を選ぶことは前向きな行為であって、過去にさかのぼって匿名性を解除するものではありません。

この不変条件が対象とするのは、label-309 レコードのバイト列だけです。トランザクションの入力に含まれる手数料支払い用の Cardano アドレス、ゲートウェイから見た発行者のネットワークレベルのアイデンティティ、オフチェーンの暗号文ブロブに含まれるメタデータは、いずれもワイヤーフォーマットの範囲外です。Label 309 はメタデータの中に存在し、トランザクションの入力の中には存在しないため、手数料支払者の突き合わせを防ぐことはできません。手数料支払者の匿名性が必要な発行者は、トランザクション構築の層でそれに対処しなければなりません。

受信者のリンク不能性

封緘済みレコードは、受信者の名前を一切記しません。受信者は、あるスロットの試行復号に成功することによってのみ、そのメッセージが自分宛てだと気づきます。読み取るべき宛先フィールドは存在しません。ここから二つの異なる保証が導かれ、両者を混同してはなりません。

一つ目は、両 KEM について、そしてあらゆる観測者について成り立ちます。

  • 受信者どうしは互いを見られない。 各スロットは、独立に包まれた鍵です。自分のスロットを開いた受信者は、ほかのスロットについて何も知ることができず、ほかに誰が宛先になっているかを知ることもできません。
  • 受信者の公開鍵はワイヤー上に乗らない。 現れるのはスロットごとのカプセル化(epk または kem_ct)と包まれた鍵だけです。候補鍵を持たない観測者は受信者を列挙できず、知れるのはスロットの数、KEM ファミリー(enc.kem)、そして封緘済みか否かの区別だけです。

二つ目は、候補となる受信者公開鍵の集合をすでに持っている敵対者が、あるスロットがそのうちの誰か宛てかどうかを試そうとする場合の保証であり、これはより強い、KEM 固有の性質です。標準はこれを古典の経路についてのみ主張します。

  • x25519 は鍵プライベートである。 スロットごとの epk は、受信者鍵とは統計的に独立な新鮮なエフェメラル公開鍵です。epkwrap だけからでは、鍵を持つ敵対者であっても、合致する秘密鍵なしに、どの候補(もしあれば)にそのスロットが宛てられているかを判定できません。
  • mlkem768x25519 はこれを主張しない。 鍵を持つ敵対者に対する受信者の匿名性は、ハイブリッド KEM の IND-CCA 安全性から 導かれない別個の性質であり、X-Wing について独立に正当化されない限り、X-Wing の経路については主張しません。鍵を持つ敵対者に対する受信者の匿名性を脅威モデルが要求するデプロイメントは、その性質をハイブリッドの経路に依拠してはなりません(MUST NOT)。上記の正直な漏えい、すなわちスロットの数、KEM ファミリー、封緘済みか否かは、両 KEM で同一であり、受信者についてそれ以上のことは、いずれの経路でも露出しません。

平文への結び付け

オンチェーンのダイジェストがコミットするのは平文であって、暗号文ではありません。封緘済みレコードによる存在証明を復号した受信者は、平文のハッシュ値を再計算し、オンチェーンの hashes マップと照合します。これは、改ざんされた暗号文を配信するストレージ層が、URI 自体の完全性モデルとは独立に、復号後に必ず検知されることを意味します。タイムスタンプの主張は、送信者がコミットした平文についての主張であり、ゲートウェイが何をしようとも、別のバイト列でこの主張を満たすことはできません。

再配信の独立性

レコードの署名は、そのトランザクションが提出された瞬間に確定します。チェーンには、トランザクションをまたいで「拡張された署名者集合」が積み上がっていく、という概念はありません。

同一のレコード本体を、別の sigs 集合とともに別のトランザクションで再配信すると、それは固有のブロック時刻を持つ別個の独立したレコードを生み出すのであって、元のレコードの拡張になることは決してない。

すでに発行されたレコードを支持したい者は、自分自身のレコードを発行します。同じコンテンツを参照するか、supersedes で先行するトランザクションを指し示すかして、自分の鍵で署名します。他人のレコードに証人として署名を付け足すわけではありません。したがって、署名済みレコードのバイト列を新しいトランザクションへ複製した攻撃者が、元のレコードの共同署名者になることはありません。攻撃者は、自分で選んだ sigs を伴う、より後の重複した主張を作り出すだけであり、元のレコードのより早いブロック時刻が、存在を示す正規の記録であり続けます。検証者やインデクサーは、同一のレコード本体を持つ二つのトランザクションを、一つの「署名者を統合した」ビューにまとめてはならない(MUST NOT)。そうした扱いは、下流の利用者が依拠する、レコードごとのブロック時刻の意味づけを偽ることになるからです。

実装に対する規範的な規則

以下は、言語やプラットフォームを問わず、いかなる準拠実装に対してもセキュリティ上の規範となります。RFC 2119 / RFC 8174 のキーワードは、規範的な意味で用います。

規則義務
独自の暗号を作らないすべてのプリミティブは、監査済みライブラリに収録された、文書化済みの IETF / NIST / W3C 標準です。自前の暗号、KDF、署名方式、ステンザは認めません。
認証付き暗号のみ対称暗号はすべて AEAD です。タグ検証の失敗は型付きのエラーを発生させなければならず(MUST)、平文の一部を黙って返してはなりません(MUST NOT)。
秘密値の比較は定数時間でMAC タグ、AEAD タグ、および秘密から導出したバイト列は、定数時間で比較します。これらの面でデータに依存した比較を行うと、認証オラクルになります。
厳格な Ed25519 検証署名は正規(厳格)モードで検証します。コファクター込みの緩い検証者は、厳格な検証者が拒否する境界事例の署名を受理してしまい、参照実装と食い違います。
秘密や平文を決してログに出さない鍵素材、導出した鍵、復号した平文は、いかなるレベルでもログに現れてはなりません(MUST NOT)。バイト型の値は無条件に伏字にします。

独自の暗号を作らない

Label 309 が認めるのは、よく分析されたプリミティブだけであり、いずれもアルゴリズムレジストリに名前が挙げられ、監査済みのライブラリで実装されています。実装は、独自の対称暗号、KDF、署名構成、鍵ラップ用ステンザを持ち込んではなりません(MUST NOT)。ワイヤーフォーマットを標準部品の組み合わせとして構成しているのは、まさにその安全性を、それら部品の安全性へと帰着させるためです。

認証付き暗号のみ

Label 309 における対称暗号は、コンテンツ層も、スロットごとの鍵ラップも、すべて AEAD です。このフォーマットのどこにも、認証のない暗号モードは存在しません。AEAD タグの検査に失敗した復号器は、安定したコード識別子を伴う構造化されたエラーを返さなければならず(MUST)、認証されていないバイト列を返す処理へ流れ込んではなりません(MUST NOT)。追加認証データはタグ計算の一部なので、AAD が誤っている場合も鍵が誤っている場合とまったく同じように失敗します。探りを入れられる中途半端な成功状態は存在しません。

秘密値の定数時間比較

実行時間が秘密のバイト列に依存する比較ループは、オラクルになります。秘密、あるいは MAC / AEAD タグに対する等価判定は、すべて定数時間でなければなりません(MUST)。

  • スロット集合の MAC およびすべての HMAC タグ。32 バイトの MAC に対する 1 バイトごとのタイミング漏えいは、敵対者が繰り返すことで、タグの復元につながりかねません。
  • AEAD タグの検証。基盤となるライブラリの decrypt は、どのバイトが一致しなかったかを明かさずに失敗を返します。実装は、この検査を自前で再実装してはなりません(MUST NOT)。
  • 署名検証。自前で組み立てた等式ではなく、ライブラリの verify を使ってください。

これらの面に触れるバイト配列に対して素朴な == / === を使うのは、欠陥です。こうした比較をすべて一つの型付きヘルパーに通すことで、この性質を監査可能にできます。

定数時間の規律は、個々の比較だけでなく、トライアル復号ループの形にも及びます。受信者を隠すという性質を保つために、受信者検証者は単一の秘密鍵のパスの中ですべてのスロットを処理しなければなりません(MUST)。鍵あたり一定回数のスロット演算で、最初の一致での早期離脱はありません。これにより、タイミングを観測できるネットワークレベルの観測者が、ある鍵がどのスロットインデックスをアンラップしたか、あるいは一致したスロットがあったかどうかすら推測できないようにします。候補鍵は定数時間で選択されます。X25519 シェアの有効性は、秘密に依存しないビット kem_ok = NOT constantTimeEqual(shared, 0^32) として捉えられます。これは早期の分岐ではなく定数時間比較で計算されます。次に KEK は、本物の KEK と、同じ salt と info のもとで全ゼロの共有秘密から導出したダミー KEK との定数時間の選択となり、kem_ok はスロットの受理(ok = kem_ok AND open_ok AND mac_ok)へ織り込まれます。こうして、ECDH が無効なスロットは決して受理されない一方で、ループは依然として同一の処理を行います。スロットの配列は CSPRNG でシャッフルされた順序で発行されるため、ワイヤー上の位置はすでに「主たる受信者が先頭」の手がかりを持ちません。定数時間のパスと組み合わさることで、観測者が知れるのはスロットの数だけです。複数の秘密鍵を持つ受信者(たとえばアイデンティティのローテーションをまたいでアーカイブされた鍵)は鍵 × スロットを走査し、鍵をまたいで短絡してもかまいません(MAY)。これは弱い「どの鍵が一致したか」の信号だけを漏らしますが、いずれか単一の鍵のスロットをまたぐ間は定数時間を保たねばならず(MUST)、鍵ごとに KEK ソルトの受信者鍵側の半分を導出し直します。どちらの KEM も、ソルトをその鍵の正規ワイヤーエンコーディング(ちょうど 32 バイトの X25519 公開鍵、またはちょうど固定の 1216 バイトの X-Wing 公開鍵バイト列であり、非正規な再エンコードは決して用いません)にコミットするからです。

厳格な Ed25519 検証

Label 309 の署名は、厳格(正規)モードで検証しなければなりません(MUST)。コファクター込みの緩い検証者は、厳格な検証者なら拒否する、可鍛性のある署名や低位数の鍵による署名の一部を受理してしまいます。これは、準拠した二つの実装が同じレコードについて食い違うことを許してしまい、標準全体が依拠する「判定は一つ」という性質を壊します。言語をまたぐ準拠コーパスは、緩いモードに陥った検証者をとらえるために、低位数のテストベクトルを厳密に固定しています。署名を参照してください。

秘密素材を決してログに出さない

シード値、導出した秘密鍵、鍵暗号化鍵、コンテンツ暗号化鍵、パスフレーズから導出した素材、そして復号した平文は、いかなるレベルでもログに到達してはなりません(MUST NOT)。ロガー設定でのパスベースの伏字化は必要ですが、それだけでは十分ではありません。伏字化のグロブが届くより深くにネストした値はすり抜けてしまうため、実装は、すべてのバイト型の値(Uint8Arraybytes など)を、たとえノンスのようなプロトコル上は公開してよい値であっても、無条件に不透明な伏字として扱わなければなりません(MUST)。守るのに最も手間のかからない秘密は、そもそもログの行に入らない秘密です。

封緘済み PoE 構成の保証

さらに三つの性質が、封緘済み PoE の構成に固有です。これらは、封緘済みレコードを生成または開封するあらゆる実装にとって、セキュリティ上規範的です。

スロット集合の MAC は ~128 ビットのコミットメントである

スロット集合の MAC は、回収されたコンテンツ鍵を、受信者が照合したスロット集合へのコミットメントにするものです。悪意ある送信者は、単一の受信者が「自分のもの」として受理する二つの異なるスロット集合を構成できません。求められる性質は、エンベロープのコンテンツ鍵に対する RFC 9771 の意味での制限付き鍵コミットメントです。すなわち、回収された鍵は単一のスロットトランスクリプトに結び付き、任意の入力に対する完全なコミット型 AEAD でありません。受信者はスロットから鍵を導出し、それを自分のスロットとして扱う前に、その同じ鍵がスロットトランスクリプトのハッシュに対して slots_mac を再現することを要求します。具体的には、このコミットメントは次の写像のマルチキー衝突耐性に依拠します。

CEK ↦ HMAC-SHA-256( HKDF-SHA-256(CEK, info="cardano-poe-slots-mac-v1"), slots_hash )

これは敵対的に選ばれた CEK とトランスクリプトについての耐性です。敵対者が CEK とトランスクリプトの両方を制御するため、関連する上限は 256 ビットの HMAC 出力に対する一般的な衝突(誕生日)上限です。すなわち、同じ slots_mac を生む二つの (CEK, transcript) の組を見つけるのは、256 ビットの第二原像のレベルではなく、~128 ビットの探索です。128 ビットの一般衝突マージンが、このコミットメントが依拠する安全性水準であり、脅威モデルに対して十分です。

HMAC の前にトランスクリプトを 32 バイトの slots_hash へ事前ハッシュしても、これは弱まりません。slots_mac の衝突は、slots_hash の衝突(SHA-256 の衝突)か、等しい slots_hash 上での鍵付き HMAC の衝突かのいずれかを含意し、いずれも ~128 ビットのレベルです。トランスクリプト自体の改ざん検知性は、SHA-256 の 2^128 衝突上限を引き継ぎます。コミット済みのヘッダーフィールドやスロットのバイトに対するいかなる変更も slots_hash を変え、異なるトランスクリプトに対して同じ slots_hash を偽造することは、まさにその ~128 ビットの衝突探索です。その直接の帰結として、スロットごとのラップはコミット型 AEAD である必要がありません。コミットメントは slots_mac が供給するのであってラップではないため、非コミット型のラップ(既定の ChaCha20-Poly1305)でも健全です。

全ゼロノンスのラップの安全性は、スロットごとの鍵の一意性に依拠する

各スロットは、コンテンツ鍵を、スロットごとの鍵暗号化鍵のもとで ChaCha20-Poly1305 を全ゼロノンスで用いてラップします。全ゼロノンスが安全なのは、鍵暗号化鍵がスロットごとであり、ちょうど一度のラップにしか使われない場合に限られます。すべてのスロットが新鮮な KEM 乱数を引くため、ラップ鍵はスロットごとに、無視できる衝突確率で一意です。安全性の条件はまさにスロットごとの鍵の一意性であり、プロデューサーは (key, nonce) の組を繰り返しうるものを一切持ち込んではなりません(MUST NOT)。KEM 乱数を繰り返す CSPRNG の故障、決定的または衝突するカプセル化、レコードをまたいだスロットの再利用、(recipient, ephemeral) による導出鍵のキャッシュ、同一受信者の二つの出現を一つのスロットへ重複排除すること、いずれもです。

これは、検証者が確認できる部分と、プロデューサーのみの義務とに、きれいに分かれます。

  • レコード内の重複は検証者が拒否する。 検証者は、カプセル化材料が単一の slots[] の中で互いに異なることを要求しなければなりません(MUST)。x25519 の経路ではすべての epk 値が、mlkem768x25519 の経路ではすべての kem_ct 値が異なっていなければなりません。重複は、いかなる KEM や AEAD のプリミティブが走る前に、型付きコード ENC_SLOTS_DUPLICATE_KEM_MATERIAL で拒否されます。適合性コーパスは、epk(または kem_ct)を共有する二つのスロットを持つレコードでこれを試し、その拒否を要求します。この拒否は、繰り返された epk / kem_ct に対してのみ発火します。同じ受信者へ二度封緘することを禁じるものではありません。正直な重複は、出現ごとに新鮮なスロットごとの KEM 乱数を引くからです(下の複数マッチスロットの規則を参照)。
  • レコードをまたぐ、鍵をまたぐ再利用はプロデューサーの義務である。 プロデューサーが二つの異なるレコードや受信者にわたって KEM 材料を再利用したことを、いかなる検証者も検知できません。それは単一のレコードのバイト列の外にあり、プロデューサーの責任に留まります。仮に将来のリビジョンが鍵の再利用を認めるなら、その同じ変更のなかで全ゼロノンスを新鮮なノンスに置き換えなければなりません。

複数マッチするスロット: パディングは許され、CEK の競合は許されない

受信者の秘密鍵が複数のスロットに正当にマッチすることもありえます(MAY)。同じコンテンツ鍵を、同じ受信者へ、それぞれ新鮮なスロットごとのエフェメラルを伴って複数のスロットに封緘することは、二つのスロットが受信者を共有していることを明かさずに、見える形のスロット数を増やす、正当なパディングおよびプライバシー技法です。これは上記のレコード内の重複カプセル化の拒否とは別物です。正直な重複は新鮮な KEM 乱数を引くため、その epk / kem_ct は異なり、決して ENC_SLOTS_DUPLICATE_KEM_MATERIAL を踏みません。したがって検証者は最初のマッチするスロットのコンテンツ鍵を選ばねばならず(MUST)、複数のスロットがマッチしたというだけで拒否してはなりません(MUST NOT)。

検証者が必ずMUST)拒否すべき唯一の異常は、異なるコンテンツ鍵を回収する 2 つのマッチするスロットです(定数時間で比較します)。トライアル復号ループは cek_conflict ビットをすべてのスロットにわたって保持し、後続のいずれかのマッチが、すでに選択済みの鍵と異なる鍵を回収した場合には、単一の汎用的な失敗を表面化させます。これは多層防御です。上記のコミットメント性質のもとでは、異なる鍵を生むマッチはすでに実現不可能であり、それはまさにその性質が排除するマルチキー衝突なので、このチェックは壊れた実装や、将来その前提が弱められた場合に対してフェイルクローズします。異なる鍵を生む否定例はバイトベクトルとして構成できません(それを構成することがコミットメントの衝突そのものになるからです)。そのためこの性質は、フィクスチャではなく実装レベルの振る舞いテストで固定され、あわせて正当な受信者重複のための正のフィクスチャが用意されています。

いかなるプリミティブよりも前のパーサのリソース上限

検証者は、いかなる KEM や AEAD のプリミティブを呼び出すよりも前に、パーサのリソース使用を制限しなければなりません(MUST)。過大なエンベロープが、拒否される前に処理コストを課せないようにするためです。参照上限は MAX_SLOTS = 1024 スロットと、デコード後の enc エンベロープに対する 65536 バイトであり、いずれも、正直なレコードを制約する約 16 KiB の Cardano トランザクションメタデータ天井をはるかに上回ります。したがってどちらかの上限を超えるレコードは不正形式です。スロット数の超過は ENC_SLOTS_TOO_MANY、サイズ超過のエンベロープは ENC_ENVELOPE_TOO_LARGE で拒否されます。これらはワイヤーフィールドではなく、検証者が強制するデプロイ固定の定数であり、デプロイ側でより厳しくしてもかまいません(MAY)。passphrase 経路における対応するガードは、正規化と Argon2id の前に強制される、生のパスフレーズ入力の最大長です(参照上限 4096 UTF-8 バイト、MAX_PASSPHRASE_INPUT_BYTES)。これにより、病的なパスフレーズが KDF 前のサービス拒否を引き起こせないようにします。

X-Wing 公開鍵の有効性がハイブリッドのフロアを支える

ハイブリッドの mlkem768x25519 KEM は、フロアとして X25519 の古典的安全性を決して下回りませんが、そのフロアは正当に生成された受信者鍵に限って適用されます。XWing.Encapsulate は、固定された X-Wing リビジョンの公開鍵有効性チェックを受信者鍵に適用しなければならず(MUST)、それに通らない鍵をあたかも古典的保証を備えているかのように扱うのではなく、その鍵へのカプセル化を拒否しなければなりません。チェックを省くプロデューサーは、その受信者についてフロアを失います。このチェックは、フロアが成り立つための前提条件です。

上限付きのペイロードサイズ

コンテンツ層はセグメント化された STREAM です。平文は 65536 バイトのチャンクに分割され、各チャンクはコンテンツ鍵のもと、それぞれ異なるカウンターノンスで封緘されます。88 ビットのチャンクごとカウンターは 2^88 個のチャンクを許容し、各チャンクは RFC 8439 の単一呼び出し上限に十分収まります。そのため、平文全体に対する single-shot の AEAD とは異なり、カウンターのオーバーフローによる鍵ストリームの衝突を警戒する必要はなく、フォーマットが暗号的なペイロード上限を課すこともありません。したがってデプロイメントが課す最大値は、暗号的な上限ではなくサービス拒否(DoS)ポリシーです。プロデューサーと検証者は、自らのリソースに合わせてペイロードサイズに上限を設けるべきであり(SHOULD)、ストリームの書き込み時または読み取り時に逐次的にそれを課し、過大なペイロードがバッファされる前に中止すべきです。切り詰めはサイズチェックではなく、チャンクごとのファイナルフラグによって構造的に捕捉されます。すなわち、ファイナルチャンクの欠落、末尾の余分なデータ、短い非ファイナルチャンクは、いずれも復号に失敗します。この構えは slots 経路でも passphrase 経路でも同一です。

セキュリティ特性としてのアルゴリズム俊敏性

Label 309 レコードにおける暗号上の選択、すなわちハッシュ、AEAD、KEM、KDF、署名方式は、いずれも拡張可能なレジストリの文字列で名指しされます。これは見た目上の選択ではなく、フォーマットがどの単一アルゴリズムよりも長く生き延びることを可能にする、移行の土台です。

あるプリミティブが暗号解析によって弱体化した場合は、次のように対処します。

  1. 該当するレジストリに、後継の識別子が追加されます。既存のフォーマットは何も変わりません。新しい名前は追加です。
  2. 既存のレコードは有効なまま残ります。 検証者は、過去のレコードについて引き続き古い識別子を認識します。より新しいアルゴリズムが登場したからといって、それらのブロック時刻の主張が消えてなくなることはありません。実装は、すでに弱体化したアルゴリズムだけに依拠するレコードを、保証の低いものとして提示してもよい(MAY)が、それだけを理由に消去したり拒否したりしてはなりません(MUST NOT)。
  3. 新しいレコードは後継のもとで発行されます。 多層的な防御を求める発行者は、設計系統の異なる二つのアルゴリズムでコンテンツのハッシュ値をコミットしてもよい(MAY)ため、一系統が破られても、レコードの証拠としての価値が崩れることはありません。もっとも、単一アルゴリズムのレコードも完全に準拠したままです。

識別子は文字列であり、レジストリは開かれているため、ポスト量子のハッシュ、KEM、署名への移行は、互換性を壊すフォーマットの改訂ではなく、レジストリへの追加変更で済みます。すでにレジストリにあるハイブリッドのポスト量子 KEM は、この性質が実際に働いている一例であって、後付けで取り付けた特例ではありません。

標準の既知の限界

これらは、後の改訂で直すべき欠陥ではありません。永続的で公開された台帳に証明を固定すること、そして長期鍵への公開鍵暗号というやり方そのものに、本質的に伴う性質です。誠実なセキュリティモデルは、これらを率直に名指しします。

オンチェーンの永続性

Cardano のメタデータは永続的で、世界中に複製されます。発行された Label 309 レコードは、削除も、編集による墨消しも、無効化もできません。その永続性こそが、存在証明の存在意義そのものです。その帰結として、発行の時点で果たすべき責任が生じます。コンテンツのハッシュ値、ステークに結び付いた署名、その他ラベル 309 のもとにコミットしたものは何であれ、永久にチェーン上に残ります。Label 309 は、オンチェーンの占有領域を最小限に保つために、自由記述の説明的なメタデータをレコードからあえて省いていますが、発行者は、自分が発行するものが取り消せないということを、発行する前に理解しなければなりません(MUST)。

受信者の数は見える

封緘済みレコードによる存在証明は、受信者の名前を一切記しませんが、受信者スロットのは配列の長さであり、チェーン上にそのまま見えています。KEM ファミリー(enc.kem)と封緘済みか否かの区別も同様です。受信者の公開鍵はワイヤー上になく、スロットはシャッフルされますが、数を隠すためのパディングはベースラインには含まれません。受信者の数それ自体が機微である送信者は、このメタデータの漏れを運用面で見込んでおく必要があります。たとえば自分でスロット集合をパディングするか、レコードを分けて発行するかです。

受信者ごとの失効はない

すでに発行された封緘済みレコードによる存在証明について、特定の受信者一人のアクセスを失効させるオンチェーンのプリミティブは存在しません。レコードがある公開鍵に向けて暗号化され、チェーン上に固定されると、その結び付きは永続的になります。これはフォーマットの不備ではなく、長期鍵への公開鍵暗号に本質的に伴う性質です。漏えいが疑われる鍵は、これから先で対処します。新しいレコードを別の鍵に宛て、必要に応じて買い手の自己責任を促す合図として上書きするレコードを発行するのであって、すでにチェーン上にあるものをさかのぼって書き換えるわけではありません。

受信者に対する前方秘匿性は、設計上ない

受信者の秘密鍵を持つ者は、それまでにその鍵宛てに送られた、封緘済みレコードによるすべての存在証明を、いつまでも復号できます。オフチェーンの暗号文は永続的で、失効のプリミティブもないため、封緘済みレコードは 世界に対しては私的だが、その受信者に対しては私的ではない という状態になります。これは、長期の公開鍵に向けて暗号化したときに当然予想される挙動です。受信者の将来の到達範囲を制限する必要がある送信者は、長期のアイデンティティ鍵ではなく、短命の受信者鍵に向けて暗号化しなければなりません。これはフォーマットが許容するものの、義務づけはしない、送信者側の選択です。

試行復号の失敗は鍵素材を漏らさない

受信者は、試行復号によって自分のスロットを見つけます。内部では、信頼できるローカルな呼び出し側の診断のためにのみ、その失敗の経路は異なる型付きコードを持ちます。「自分の鍵では開くスロットがなかった」(WRONG_RECIPIENT_KEY)、「スロットは開いたが、どの候補鍵も slots_mac を再現しなかった」(TAMPERED_HEADER)、「鍵が回収され MAC が検証された後にコンテンツ AEAD が失敗した」(TAMPERED_CIPHERTEXT)の三つです。これらのコードはオラクルとしての価値を持ちません。一致する秘密鍵を持たない敵対者は、そもそもどのスロットも開けませんし、どの失敗経路も、基盤となる秘密のバイト列(共有秘密、鍵暗号化鍵、コンテンツ暗号化鍵)を、そのメッセージや原因の連鎖から除外しなければなりません(MUST)。

一方で、信頼できない外部の呼び出し側は、復号が失敗した理由にかかわらず、ちょうど 1 つの汎用的な失敗の形を受け取らねばならず(MUST)、外部の応答はその三つの原因を、形によって区別してはならずMUST NOT)、どのスロットがマッチしたかも明かしてはなりません。内部コードはローカルなデバッグのために存在するのであって、区別可能な応答を通じて外部の観測者に漏れてはなりません(MUST NOT)。

タイミングモデルは意図的にスコープが限定されています。検証者は、ノーマッチのチェックの時点で、すなわちコンテンツの復号の前に、戻ってもかまいません(MAY)。そのため、受信者でない者(どのスロットも開かなかった)は、スロットは開いたがコンテンツ暗号文の開封に失敗する受信者とは、時間で区別されうります。その区別が明かすのは受信者か否かだけであり、どのスロットがマッチしたかも、いかなる鍵材料も決して明かしません。受信者でない者のケースと、暗号文が不正なケースとの間で、タイミングを一様にすることは要求されませんNOT)。ダミーのコンテンツ開封を義務づけてはなりませんMUST NOT)。受信者でないすべての者にコンテンツ復号のコストを強いても、得るものは何もないからです。確かに成り立つ定数時間の保証は、スロット横断の不変条件です(秘密値の定数時間比較を参照)。すなわち、単一の鍵のパスの中で、ループは定数時間比較ですべてのスロットを走るため、観測者は、ある鍵がどのスロットをアンラップしたか(あるいはどれもアンラップしないか)を知ることができません。そして、受信者か否かの区別を超えては、スロットの数だけを知ります。

関連ページ

  • はじめに — 発行者非依存と単独で検証可能を含む、5 つの不変条件。
  • 署名 — 厳格な Ed25519 検証と、失敗しても落ちない著作者性モデル。
  • 封緘済みレコードによる存在証明 — 暗号化のエンベロープと、ここで要約したプライバシー特性。
  • アルゴリズムレジストリ — アルゴリズム俊敏性を可能にする名前付きの識別子。
  • 検証 — パイプライン、確認数のポリシー、そしてエラーカタログ。