プリミティブとインターフェース

次に、Tink で使用される 2 つの重要な言語である PrimitiveInterface を(非公式に、より正式に)定義します。

基本ロール

プリミティブは、タスクを安全に実行するすべてのアルゴリズムに対応する数学的なオブジェクトです。たとえば、AEAD プリミティブは、Tink が Aead に要求されるセキュリティ特性を満たすすべての暗号化アルゴリズムで構成されます。

プリミティブは、プログラミング言語やアクセス方法に縛られないことを強調します。プリミティブは純粋な数学的なオブジェクトとして考える必要があります。たとえば、AEAD は基本的に、暗号化を行う関数と復号を行う関数のペアで構成されます。

インターフェース

インターフェースとは、ユーザーがプリミティブにアクセスできるようにする方法です。たとえば、将来的には Mac インターフェースだけでなく、StreamingMac インターフェースも提供されることが期待されています。これにより、メモリに直接読み込まれないデータの MAC を計算できます。

ここでは、インターフェースとプリミティブを明示的に区別しています。これにより、2 つのインターフェースがアクセスする数学オブジェクトが同じであることが明確になります。

正式な定義

ほとんどの読者にとって、上記の直感的な説明で十分でしょう。それでも、Google では、こうしたコンセプトの正式な定義を提供することが重要な場合があると考えています。

暗号関数

暗号関数の概念はプリミティブのコンセプトほど重要ではありませんが、プリミティブを正式に定義するためにそれを導入する必要があります。

暗号関数

暗号関数は、1 つのマップの

\[ f: {\bf K} \times {\bf R} \times {\bf I} \to {\bf O}\]

集合 \({\bf K}\) (キー空間)、集合 \({\bf R} = \{0,1\}^{\infty}\)(ランダム性。無限のビット文字列のセットであると仮定)、集合 \({\bf I}\) (入力空間)から集合 \({\bf O}\) (出力空間)に格納されます。

なぜ特定のランダム性パラメータを追加したのかは、後で明らかになります。

例として、これらのコンセプトを AES-GCM にマッピングする方法を 1 つ示します。有効な鍵サイズ \(s_k\)、ノンスサイズ \(s_n\)、タグサイズ\(s_t\)ごとに、AES-GCM は 2 つの暗号関数(暗号化用と復号用)で構成されています。どちらも同じキースペース \({\bf K} = \{0,1\}^{s_k}\)を持ちます。

暗号化関数 \(\mathrm{Enc}\)では、ランダム性の最初の \(s_n\) ビットを使用してノンスが選択されます。

\({\bf B} = \{0,1\}^8\) は 1 バイトを表します。 暗号化関数の入力空間は、 \({\bf I} = {\bf B}^{*} \times {\bf B}^{*}\) 任意の長さのバイト文字列のペアです。 ペアの最初の要素はメッセージ、2 番目の要素は関連データです。AES-GCM 標準では入力の長さに上限がありますが、Google は任意の長さを許容し、代わりに特別なエラーシンボル \(\bot\) を出力スペースに追加します。出力空間は \({\bf O} = {\bf B}^* \cup \{\bot\}\)になります。ここでは、成功した計算の結果を標準で規定されている連結として \((\mathrm{IV} \| \mathrm{ciphertext} \| \mathrm{tag})\) として定義し、入力が長すぎる場合は出力\(\bot\)とします。したがって、固定鍵の場合、暗号化関数は \(\mathrm{Enc}_k : {\bf R} \times {\bf B}^* \times {\bf B}^* \rightarrow {\bf B}^* \cup \{\bot\}\)型になります。

復号関数の場合、 \(\mathrm{Dec}\) 鍵空間は同じです。入力空間は同じである \({\bf I} ={\bf B}^* \times {\bf B}^*\)ですが、1 つ目の要素は暗号化関数の出力用となり、2 つ目の要素は関連データになります。

出力空間もたまたま同じになります \({\bf O} = {\bf B}^* \cup \{\bot\}\) (これも偶然です)。 \(\bot\) は通常認証エラーを示します(ただし、一部の入力が長すぎる場合の出力でもあります)。

Google は、上記の形式化が標準を形式化する唯一の選択肢ではないことに強調します。たとえば、ランダム性からノンスを読み取る(その結果として非常に異なるプリミティブになる)代わりに、ノンスを入力の一部と見なすこともできます。あるいは、出力を、(連結ではなく)ノンス、暗号テキスト、タグを含む 3 つの組み合わせとして定義することもできます。または、キースペースを(ある程度任意に)\({\bf K} = \{0,1\}^{128} \cup \{0,1\}^{256}\)に制限することもできます。

暗号アルゴリズム:

(対称)暗号アルゴリズムはタプルである

\[(f_1, ... f_k)\]

すべての関数が同じキー空間を持つ暗号関数です。暗号アルゴリズムのタイプはタプル \((({\bf I}_1, {\bf O}_1), \ldots, ({\bf I}_k, {\bf O}_k))\)です。

たとえば、鍵、ノンス、タグサイズの \((s_k, s_n, s_t)\) 有効なトリプルごとに、AES-GCM は上記の 2 つの関数と \((s_k, s_n, s_t)\) 上記の 2 つの関数を持つ暗号アルゴリズムです。 \(\mathrm{Enc}\) \(\mathrm{Dec}\)\({}_{s_k, s_n, s_t}\)

プリミティブとインターフェース

次に、暗号プリミティブを定義します。

基本ロール
プリミティブは暗号アルゴリズムのセットであり、すべてのアルゴリズムのタイプは同じ \((({\bf I}_1, {\bf O}_1), \ldots, ({\bf I}_k, {\bf O}_k))\)で、アルゴリズムのキースペースはペア単位で互いに素なものです。

例として、Tink の \(\mathrm{AEAD}\) プリミティブについて考えてみましょう。アルゴリズムが複数あり、中には、鍵サイズが 128 および 256 ビットの AES-GCM、ノンスサイズが 96 ビットの AES-EAX、いくつかの鍵サイズの AES-EAX、XChaCha20Poly1305 などがあります。それらは互いに素な鍵空間を持っていますが、すべて同じ暗号関数\(\mathrm{Enc}\) と \(\mathrm{Dec}\)を提供します。(この正式な説明では、AES-GCM のさまざまな鍵サイズをなんらかの方法で折りたたむ目的は考えていませんが、もちろんできます)。

プリミティブの定義

プリミティブの一般的な考え方は、最初に暗号関数のプロパティを定義し、次に単純に、プリミティブをすべてそのようなアルゴリズムであるとみなすということです。

たとえば、AEAD の場合、 \(\mathrm{Dec}_k(\mathrm{Enc}_k(m, a), a) = m\) が「常に」満たされていると言います(平文 \(m\) が長すぎる場合などは除きます)。さらに、ランダム鍵の場合、暗号化は半期的に安全であるなど、セキュリティ特性もあります。

AEAD プリミティブは、これらのプロパティを満たすすべての暗号アルゴリズムのセットです。つまり、実際には、特定のプリミティブを定義するときは、プロパティに基づいて定義します。定義にあるとおり、アルゴリズムのリストは提供していません。

インターフェース

Tink のインターフェースは、入力空間から出力空間の要素を計算できるという意味で、プリミティブへのアクセスを提供します。たとえば、Java の AEAD インターフェースについて考えてみましょう。

public interface Aead {
  byte[] encrypt(byte[] plaintext, byte[] associated_data) throws GeneralSecurityException;
  byte[] decrypt(byte[] ciphertext, byte[] associated_data) throws GeneralSecurityException;
}

なお、ランダム性にはアクセスできません。代わりに、ユーザーが入力空間の要素を指定できます。ランダム性へのアクセスを禁止するのは当然のことです。1

Tink は、1 つのプリミティブに複数のインターフェースを提供することがあります。要件が異なることがあるため、これは非常に便利です。ただし、これには代償が伴います。一般に、提供するインターフェースが多いほど、相互運用性は低くなります。たとえば、(内部で暗号化するために)Aead オブジェクトを渡す必要がある Tink に基づくライブラリを作成しているとしましょう。Tink が \(\mathrm{AEAD}\) プリミティブに対して提供するインターフェースが多すぎると、ユーザーが選択したキーとライブラリで同時に機能するインスタンスの準備が整っていない可能性が高くなります。そのため、インターフェースを増やすことはトレードオフとなります。


  1. AEAD 暗号には、選択された暗号テキスト攻撃に対して安全であるという特性があります。これは、ノンスの再利用がない場合にのみ保証されます。Tink の Aead インターフェースは、ノンスの再利用を防ぐように設計されています。ユーザーは暗号化用の入力としてノンスを指定できません。代わりに、暗号化操作ごとに新しいノンスがランダムに生成されます。