メインコンテンツまでスキップ

10. セキュリティに関する考慮事項

この節では、この文書で説明されている hash-to-curve メカニズムに関する追加のセキュリティ上の考慮事項について述べます。

10.1. エンコーディングの属性

各エンコードタイプ(第3節)は、任意のバイト文字列を受け取り、エンコードタイプに依存した分布からサンプリングされた曲線上の点にマッピングします。非一様エンコーディングを使用したり、第6節のマッピングを直接評価したりして得られる出力は、一様ランダムな点と容易に区別できることに注意することが重要です。非一様エンコーディングを使用するアプリケーションは、非一様性がセキュリティに与える影響を慎重に分析すべきです。必要なエンコーディングが不明な場合は、一様エンコーディングを使用すべきです。

第3節で示される2つのエンコーディングは、どちらも群 G の単位元(無限遠点)を出力する可能性があります。いずれかのエンコード関数がランダムな入力に対して単位元を出力する確率は、およそ 1/r(r は群の位数)であり、暗号学的に有用な楕円曲線にとっては無視できる値です。さらに、対応する出力が単位元となるようなエンコード関数への入力を取得することは計算上不可能です。(第5節のすべてのガイドラインに従った hash_to_field 関数を使用してエンコード関数がインスタンス化されている場合、これら両方の属性が保持されます。)これらのエンコード関数を使用するプロトコルでは、単位元を検出して「修正」するための特別なケースを追加すべきではありません。

hash_to_curve 関数(第3節)が、ランダムオラクルと識別不能な hash_to_field 関数(第5節)を使用してインスタンス化されている場合、結果として得られる関数はランダムオラクルと識別不能になります ([MRH04] [BCIMRT10] [FFSTV13] [LBB19] [H20])。多くの場合、このような関数は、セキュリティ分析においてランダムオラクルが楕円曲線上で一様ランダムな点を出力することを前提としている暗号プロトコルで安全に使用できます。ただし、Ristenpart らが [RSS11] で議論しているように、ランダムオラクルに依存するすべての安全性証明が、それらのオラクルを識別不能な関数で置き換えた後も保持されるわけではありません。hash_to_curve 関数に依存するプロトコルの安全性を分析する際には、この制限を考慮する必要があります。

10.2. パスワードのハッシュ

この文書で説明されている関数を使用してパスワードをハッシュする場合、ハッシュ関数の出力(または hash_to_field の出力などの潜在的な中間値)を知っている敵対者は、辞書攻撃を実行できる可能性があります。このような攻撃を軽減するために、まずパスワードに対してよりコストのかかる鍵誘導関数(例えば PBKDF2 [RFC8018]、scrypt [RFC7914]、Argon2 [RFC9106] など)を実行し、その関数の出力をターゲットの楕円曲線にハッシュすることを推奨します。衝突耐性を確保するため、鍵誘導関数の基礎となるハッシュは、第5.3.1節にリストされているガイドラインに従って選択されるべきです。

10.3. 定数時間の要件

すべての用途において、サイドチャネルを通じた情報の漏洩を避けるために、この文書のすべての関数を定数時間(constant-time)で実装することを強く推奨します(STRONGLY RECOMMENDED)。エンコーディングへの入力が秘密の値である場合、定数時間の実装は特に重要です。この場合、定数時間の実装はタイミング攻撃(例:[VR20])に対する防御に必須です。定数時間の実装が必要な場合、第4節で説明されているように、すべての基本操作およびユーティリティ関数を定数時間で実装しなければなりません(MUST)。一部のアプリケーション(例:組み込みシステム)では、他のサイドチャネル(例:消費電力や電磁波)を通じた漏洩が関係する場合もあります。漏洩の性質や適切な防御策はアプリケーションに依存するため、そのような漏洩に対する防御はこの文書の範囲外です。

10.4. encode_to_curve: 出力分布と識別不能性

encode_to_curve 関数(第3節)は、統計的に一様分布から遠い分布からサンプリングされた点を返します。この分布は、大まかに次のように制限されます。第一に、少なくとも G 内の点の 8 分の 1 を含みます。第二に、分布内の点の確率の変動は最大で 4 倍です。これらの境界は、encode_to_curve が第6節のいずれかの map_to_curve 関数を使用してインスタンス化されている場合に保持されます。

上記の境界は、文献におけるいくつかの研究から導出されています。具体的には以下のとおりです。

  • Shallue と van de Woestijne [SW06]、および Fouque と Tibouchi [FT12] は、Shallue-van de Woestijne マッピング(第6.6.1節)の境界を導出しました。

  • Fouque と Tibouchi [FT10]、および Tibouchi [T14] は、簡略化 SWU マッピング(第6.6.2 および 6.6.3 節)の境界を導出しました。

  • Bernstein ら [BHKL13] は、Elligator 2 マッピング(第6.7.1 および 6.8.2 節)の境界を導出しました。

encode_to_curve の識別不能性は、Brier ら [BCIMRT10] によって示された議論と同様の論理に従います。その論理を簡単に概説します。encode_to_curve によって呼び出される map_to_curve 関数から誘導される分布からサンプリングする、理想的なランダムオラクル Hc() を考えます。便宜上、ターゲット楕円曲線の余因子が 1 であると仮定します(余因子が 1 でない場合も同様の議論が適用されます)。encode_to_curve 内部で呼び出される「内部」ランダムオラクル、すなわち hash_to_field を効率的にシミュレートできれば、識別不能性が成り立ちます。シミュレータは次のように動作します。新しいクエリ msg に対して、シミュレータは Hc(msg) を照会し、map_to_curve の像(image)内の点 P を受け取ります(msg が以前のクエリと同じ場合、シミュレータはそのクエリに対して以前に与えた値を返して応答します)。次にシミュレータは、map_to_curve における P の可能な逆像(preimage)、すなわち map_to_curve(u) == P となる有限体 F の要素 u を計算します(Tibouchi [T14] は、Shallue-van de Woestijne および簡略化 SWU マッピングにおいて、これが効率的に実行可能であることを示しており、Bernstein らは Elligator 2 についてもこれを示しています)。シミュレータは、そのような逆像を1つランダムに選択し、この値を「内部」ランダムオラクルのシミュレートされた出力として返します。仮定により、Hc() は F の一様ランダムな入力要素に対して map_to_curve から誘導される分布からサンプリングするため、この値は一様ランダムであり、map_to_curve を通じた際に正しい点 P を誘導します。

10.5. hash_to_field のセキュリティ

expand_message(第5.3節)がランダムオラクルとしてモデル化されている場合、第5節で定義されている hash_to_field 関数は、ランダムオラクル [MRH04] と識別不能です。識別不能性の証明は構成可能(composable)であるため、ランダムオラクルとしてモデル化された基礎となるプリミティブに対して expand_message がランダムオラクルと識別不能であることが証明されていれば、これも成り立ちます。第5.3節のガイドラインに従っている場合、同節で定義されている expand_message の2つのバリアントはいずれもこの要求を満たします(第10.6節も参照)。

hash_to_field の識別不能性の議論を非常に簡単に概説します。hash_to_field が返す各整数 mod p(すなわち、F のベクトル表現の各要素)は、すべて mod p で等しい、長さ log2(p) + k ビットの約 2^k 個の整数の同値類のメンバーになっています。hash_to_field によって返される各整数 mod p に対して、シミュレータはこの同値類のメンバーをランダムにサンプリングし、I2OSP によって返されるバイト文字列を出力します。(これは本質的に hash_to_field 手順の逆プロセスであることに注意してください。)

10.6. expand_message_xmd のセキュリティ

第5.3.1節で定義されている expand_message_xmd 関数は、以下のいずれかが成り立つ場合にランダムオラクル [MRH04] と識別不能になります。

  1. H がランダムオラクルと識別不能である場合。

  2. H がスポンジベースのハッシュ関数であり、その内部関数がランダム変換またはランダム置換としてモデル化されている場合 [BDPV08]。

  3. H が Merkle-Damgaard ハッシュ関数であり、その圧縮関数がランダムオラクルとしてモデル化されている場合 [CDMP05]。

ケース (1) および (2) について、expand_message_xmd の識別不能性は、H の識別不能性から直接導かれます。

ケース (3)、すなわち H が Merkle-Damgaard ハッシュ関数である場合、識別不能性は [CDMP05] の定理 5 に従います。具体的には、expand_message_xmd は、メッセージの前にゼロブロックを付加し、さらに関連情報(長さ、カウンタ、DST)を付加して b_0 を計算します。次に、expand_message_xmd の各出力ブロック b_i (i >= 1) は、b_0 の一意でプレフィックスフリーなエンコーディングに対して H を呼び出した結果となります。これは、第一に、そのようなすべての呼び出しへの入力の長さが等しく、H と DST の選択によって固定されているためであり、第二に、そのような各入力が一意のサフィックス(カウンタバイト I2OSP(i, 1) を含むため)を持っているためです。

[CDMP05] で議論されている構成と expand_message_xmd の本質的な違いは、後者が b_0 ではなく strxor(b_0, b_(i - 1))(第5.3.1節のステップ10)にカウンタを付加する点です。このアプローチは、H の異なる呼び出しへの入力間のハミング距離を増大させ、それにより H の非理想性が b_i 値の分布に影響を与える可能性を低減させます。

expand_message_xmd は、上記のいずれかの基準を満たす任意のハッシュ関数に基づいて、可変長の出力を持つ汎用的な識別不能機能をインスタンス化するために使用できることを指摘しておきます。hash_to_field 以外で expand_message_xmd を使用するアプリケーションは、DST に異なる値を選択することでドメイン分離を確保すべきです。

10.7. expand_message バリアントのドメイン分離

第2.2.5節で述べたように、ドメイン分離の目的は、複数の独立したランダムオラクルを照会する暗号プロトコルにおいて、それらすべてのランダムオラクルが1つの基礎となる関数 H をベースにインスタンス化されている場合であっても、セキュリティ分析が依然として有効であることを保証することにあります。

この文書の expand_message バリアント(第5.3節)は、H(基礎となるハッシュ関数または拡張可能出力関数)によってハッシュされるすべての文字列に、プレフィックスフリーにエンコードされたドメイン分離タグ DST_prime を付加することで、ドメイン分離を確保しています。(第5.3.4節のガイドラインに従う他の expand_message バリアントも同様の動作をすることが期待されますが、ケースバイケースで分析されるべきです。)安全性のために、expand_message 以外で同じ関数 H を使用するアプリケーションは、それらの H の使用と expand_message との間でドメイン分離を強制すべきであり、またそれらすべてを他のアプリケーションにおける H の使用から分離すべきです。

この節では、expand_message のバリアントとドメイン分離を強制するための4つの方法を提案し、各方法がどのようにドメイン分離を実現するかを説明し、各方法が適用されるケースをリストします。これらの方法は共通のハイレベルな構造を持っています。アプリケーション設計者は DST_prime とは異なるタグ DST_ext を固定し、DST_ext を使用して H への呼び出しを拡張します。各方法は異なる方法で H への呼び出しを拡張し、各方法において DST_ext に追加の要件が課される場合があります。

これらの方法は、関数ごとに異なる DST_ext 値(例:DST_ext1, DST_ext2)を選択することで、複数のドメイン分離された関数(例:H1, H2)をインスタンス化するために使用できます。

  1. (サフィックスのみのドメイン分離)この方法は、H への呼び出しを expand_message_xmd または expand_message_xof からドメイン分離するのに適しています。HMAC-H [RFC2104] と expand_message をドメイン分離するのには適していません。その場合は方法 4 を参照してください。

    サフィックスのみでドメイン分離された関数 Hso をインスタンス化するには、次を計算します。

    Hso(msg) = H(msg || DST_ext)

    同じ値にハッシュされる異なる (msg, DST_ext) のペアを見つけることを困難にするために、DST_ext はプレフィックスフリーにエンコードされるべきです(例:DST_ext の長さをエンコードした1バイトを付加する)。

    この方法は、H へのすべての異なる呼び出しが異なるサフィックス(DST_ext は DST_prime とは異なるため)を持つため、ドメイン分離を保証します。

  2. (プレフィックスおよびサフィックスによるドメイン分離)この方法は、サフィックスのみの方法と同じケースで使用できます。

    プレフィックスおよびサフィックスでドメイン分離された関数 Hps をインスタンス化するには、次を計算します。

    Hps(msg) = H(DST_ext || msg || I2OSP(0, 1))

    同じ値にハッシュされる異なる (msg, DST_ext) のペアを見つけることを困難にするために、DST_ext はプレフィックスフリーにエンコードされるべきです(例:DST_ext の長さをエンコードした1バイトのプレフィックスを付加する)。

    この方法は、追加されたバイト I2OSP(0, 1) が、Hps 内部の H への入力が expand_message 内部の入力とは異なることを保証するため、ドメイン分離を保証します。具体的には、DST_prime の最後のバイトは DST の長さをエンコードしており、これはゼロであってはならない(第3.1節の要件2)とされており、DST_prime は常に expand_message 内部の H への呼び出しにおいて付加されます。

  3. (プレフィックスのみのドメイン分離)この方法は、H への呼び出しを expand_message_xmd からドメイン分離する場合にのみ適用可能です。expand_message_xof や HMAC-H に対するドメイン分離は提供しません。

    プレフィックスのみでドメイン分離された関数 Hpo をインスタンス化するには、次を計算します。

    Hpo(msg) = H(DST_ext || msg)

    この方法によってドメイン分離を提供するためには、DST_ext は少なくとも b ビット(b はハッシュ関数 H の出力ビット数)の長さがなければなりません。さらに、最初の b ビットのうち少なくとも1ビットはゼロであってはなりません。最後に、同じ値にハッシュされる異なる (msg, DST_ext) のペアを見つけることを困難にするために、DST_ext はプレフィックスフリーにエンコードされるべきです(例:DST_ext の長さをエンコードした1バイトのプレフィックスを付加する)。

    この方法は次のようにドメイン分離を保証します。まず、DST_ext はその最初の b ビットの中に少なくとも1つのゼロでないビットを含んでいるため、値 Z_pad(第5.3.1節のステップ4)とは異なることが保証されます。これにより、H へのすべての入力が、expand_message_xmd 内で b_0 を生成するために使用される入力とは異なることが保証されます。第二に、DST_ext は少なくとも b ビットの長さがあるため、値 b_0 や strxor(b_0, b_(i - 1)) と一致することはほぼなく、したがって、H へのすべての入力が、b_i (i >= 1) を生成するために使用される入力と異なることが極めて高い確率で保証されます。

  4. (XMD-HMAC ドメイン分離)この方法は、HMAC-H(すなわちハッシュ関数 H を使用してインスタンス化された HMAC [RFC2104])内部で行われる H の呼び出しを、expand_message_xmd からドメイン分離するのに適しています。また、以下に説明するように、HKDF-H(すなわちハッシュ関数 H を使用してインスタンス化された HKDF [RFC5869])にも適しています。

    具体的には、この方法は、HMAC-H がハッシュ関数 H に基づいて非公開鍵(non-secret key)を使用してランダムオラクルをインスタンス化する場合に適用されます(expand_message_xmd もこの目的に使用できることに注意してください。第10.6節を参照)。高いエントロピーを持つ秘密鍵を使用して HMAC-H を使用する場合、ドメイン分離は不要です。以下の議論を参照してください。

    expand_message_xmd とのドメイン分離を保証する非公開の HMAC 鍵 DST_key を選択するには、次を計算します。

    DST_key_preimage = "DERIVE-HMAC-KEY-" || DST_ext || I2OSP(0, 1)
    DST_key = H(DST_key_preimage)

    次に、HMAC-H を使用してランダムオラクル Hro をインスタンス化するには、次を計算します。

    Hro(msg) = HMAC-H(DST_key, msg)

    DST_key_preimage の末尾のゼロバイトは、この値が expand_message_xmd 内部の H への入力とは異なることを保証します(上述のとおり、そのようなすべての入力は DST_prime をサフィックスとして持ちますが、DST_prime はゼロバイトで終わることはできないためです)。これにより、圧倒的な確率で、鍵 DST_key を使用した HMAC-H 内部の H へのすべての入力のプレフィックスが、expand_message_xmd 内部の値 Z_pad, b_0, および strxor(b_0, b_(i - 1)) とは異なることが保証され、ドメイン分離が実現されます。

    固定された高エントロピーの秘密鍵を通じてプライベートなランダムオラクルをインスタンス化する HMAC-H の用途では、expand_message_xmd とのドメイン分离は不要です。これは、上記と同様に、この秘密鍵を使用した HMAC-H 内部の H へのすべての入力が、expand_message_xmd 内部の H へのすべての入力とは異なるプレフィックスをほぼ確実に持つためです。

    最後に、この方法は、HKDF-Extract のソルト入力を上記のように計算された DST_key に固定することによって、HKDF-H [RFC5869] と共に使用することができます。これは、DST_key を使用した HMAC-H の場合と同じ議論によって、HKDF-Extract のドメイン分離を保証します。さらに、HKDF-Extract に提供される入力鍵材料 (IKM) が十分に高いエントロピー(例えば、セキュリティパラメータに見合ったもの)を持っていると仮定すると、HKDF-Expand ステップは、高エントロピー秘密鍵を持つ HMAC-H と同じ議論によってドメイン分離されます(疑似乱数鍵がまさにそうであるためです)。

10.8. ターゲットセキュリティレベル

各暗号スイートは、基礎となる曲線に対してターゲットセキュリティレベル(ビット単位)を指定しています。このパラメータは、対応する hash_to_field のインスタンス化が保守的かつ正解であることを保証するためのものです。強調しておきたいのは、このパラメータはあくまで曲線のセキュリティレベルの上限であり、特定のアプリケーションに対する適合性を保証または推奨するものではないということです。数学や暗号学の進歩により、いかなる曲線の実効的なセキュリティレベルも低下する可能性があります。