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

5.2 Encryption and Decryption (暗号化と復号化)

5.2 Encryption and Decryption (暗号化と復号化)

HPKE は, 与えられたセットアップトランザクションに基づいて複数の暗号化操作を実行できます。セットアップに関与する公開鍵操作は通常, 対称暗号化や復号化よりも高価であるため, これによりアプリケーションは公開鍵操作のコストを償却し, 全体的なオーバーヘッドを削減できます。

ただし, nonce の再利用を避けるために, この暗号化はステートフルでなければなりません。上記の各セットアップ手順は, AEAD と秘密エクスポートパラメータを格納する役割固有のコンテキストオブジェクトを生成します。AEAD パラメータは以下で構成されます:

  • 使用中の AEAD アルゴリズム

  • 秘密鍵

  • ベース nonce base_nonce

  • シーケンス番号 (最初は 0)

秘密エクスポートパラメータは以下で構成されます:

  • 使用中の HPKE 暗号スイート, および

  • 秘密エクスポートインターフェースに使用される exporter_secret (5.3節 を参照)

AEAD シーケンス番号を除いて, これらのパラメータはすべて定数です。シーケンス番号は nonce の一意性を提供します: 各暗号化または復号化操作に使用される nonce は, base_nonce と現在のシーケンス番号を XOR した結果であり, シーケンス番号は base_nonce と同じ長さのビッグエンディアン整数としてエンコードされます。実装は nonce の長さより短いシーケンス番号を使用してもかまいませんが (左側をゼロでパディング), シーケンス番号がオーバーフローする場合はエラーを発生させなければなりません。AEAD アルゴリズムは平文より Nt バイト長い暗号文を生成します。この文書で定義された AEAD アルゴリズムの場合, Nt = 16 です。

暗号化は送信者から受信者への一方向です。送信者のコンテキストは, 関連データ aad を使用して平文 pt を暗号化できます:

def ContextS.Seal(aad, pt):
ct = Seal(self.key, self.ComputeNonce(self.seq), aad, pt)
self.IncrementSeq()
return ct

受信者のコンテキストは, 関連データ aad を使用して暗号文 ct を復号化できます:

def ContextR.Open(aad, ct):
pt = Open(self.key, self.ComputeNonce(self.seq), aad, ct)
if pt == OpenError:
raise OpenError
self.IncrementSeq()
return pt

各暗号化または復号化操作は, 使用中のコンテキストのシーケンス番号をインクリメントします。メッセージごとの nonce とシーケンス番号のインクリメントの詳細は以下の通りです:

def Context<ROLE>.ComputeNonce(seq):
seq_bytes = I2OSP(seq, Nn)
return xor(self.base_nonce, seq_bytes)

def Context<ROLE>.IncrementSeq():
if self.seq >= (1 << (8*Nn)) - 1:
raise MessageLimitReachedError
self.seq += 1

送信者のコンテキストは復号化に使用してはなりません。同様に, 受信者のコンテキストは暗号化に使用してはなりません。より一般的な目的で HPKE 鍵交換を再利用する上位レベルのプロトコルは, 秘密エクスポートインターフェースを使用して必要に応じて個別の鍵マテリアルを導出できます; 詳細については5.3節と9.8節を参照してください。

暗号化と復号化の nonce が一致するように, 暗号化と復号化が適切な順序で実行されることを保証するのはアプリケーションの責任です。ContextS.Seal() または ContextR.Open() が seq フィールドをオーバーフローさせる場合, 実装はエラーで失敗しなければなりません。(以下の擬似コードでは, seq がオーバーフローすると Context<ROLE>.IncrementSeq() がエラーで失敗し, それによって ContextS.Seal() と ContextR.Open() が対応して失敗します。) 内部の Seal() と Open() の呼び出しはコンテキストの AEAD アルゴリズムに対応していることに注意してください。