ZigでCamelliaブロック暗号を実装する
はじめに
3年近く前にCamelliaのRust実装のcamellia
クレートを書きましたが、最近はZigも少し書くようになったのでZigでも実装してみたいと思って実装しました。
この記事では、上記の実装を参照しながらCamelliaを実装する方法について述べたいと思います。
Camelliaについて
Camelliaは、2000年にNTTと三菱電機によって開発されたブロック暗号です。
CamelliaのインターフェースはAES互換で、ブロック長は128ビット、鍵長は128ビット、192ビット、256ビットです。
CamelliaはAESと同等の安全性と処理性能を有しており、AESと同じくCRYPTRECの電子政府推奨暗号リストに載っています。
CamelliaのアルゴリズムはRFC 3713で説明されています。
RFCの日本語訳もあります。
実装
RFCで仕様が説明されているので、そのとおりに実装すれば暗号化と復号ができます。
Camelliaでは鍵スケジュール部で与えられた鍵から副鍵を生成して、生成した副鍵を使って暗号化と復号を行います。
定数
Camelliaではマスク用の定数値MASK8
、MASK32
、MASK64
、MASK128
が定義されています。
今回の実装ではMASK8
、MASK128
は使用しないので実装内で定義していません。
鍵スケジュール
鍵スケジュール部では与えられた鍵K
から暗号化と復号に使用する副鍵を生成します。
鍵スケジュール部では128ビット変数のKL
、KR
、KA
、KB
を使用します。
KL
、KR
は鍵K
から生成します。
Camellia-128の場合は128ビット鍵K
をKL
として使用し、KR
には0を設定します。
RFCにはバイトオーダーについて書かれていませんが、アルゴリズム仕様書にバイトオーダーがビッグエンディアンあると書かれているのでK
をビッグエンディアンで読み取ります。
Camellia-192の場合は192ビット鍵K
の上位128ビットをKL
として使用し、K
の下位64ビットを64桁左シフトした値とK
の下位64ビットをビット反転した値の論理和をKR
として使用します。
Camellia-256の場合は256ビット鍵K
の上位128ビットをKL
として使用し、K
の下位128ビットをKR
として使用します。
KA
、KB
はKL
、KR
から生成します。
KA
、KB
の生成時に使用する64ビット定数Sigma1
からSigma6
は以下のように定義されています。
副鍵はこれらの変数を左循環シフトした結果の上位64ビットか下位64ビットを使用して生成します。
Camellia-128の場合はKL
、KA
を使用して64ビットの副鍵kw
(ホワイトニングで使用)4個、k
(ラウンド鍵)18個、ke
(6ラウンドごとに使用)4個の計26個生成します。
Camellia-192、Camellia-256の場合はKL
、KR
、KA
、KB
を使用して64ビットの副鍵kw
(ホワイトニングで使用)4個、k
(ラウンド鍵)24個、ke
(6ラウンドごとに使用)6個の計34個生成します。
Zigで左循環シフトはstd.math.rotl
でできます。
暗号化
暗号化では最初に128ビットの平文M
を上位64ビットのD1
と下位64ビットのD2
に分割します。
18ラウンド(Camellia-128)または24ラウンド(Camellia-192、Camellia-256)のFeistel構造を使って行います。
6ラウンドごとにFL関数とFLINV関数を挿入します。
128ビットの暗号文C
はD2
を64桁左シフトした値とD1
の論理和です。
復号
復号は副鍵の順序を反転させて暗号化と同じ処理をすることで行えます。
コンポーネント
F関数
ラウンド関数Fはhttps://datatracker.ietf.org/doc/html/rfc3713#section-2.4.1で説明されています。
今回の実装ではRFCのものよりも高速に処理できることからBotanのF関数を利用しています。
Camelliaでは4つのS-boxを使用します。
SBOX1
は以下のように定義されています。
SBOX2
からSBOX4
は以下の式で求めることができます。
sbox_2[x] = math.rotl(u8, sbox_1[x], 1);
sbox_3[x] = math.rotl(u8, sbox_1[x], 7);
sbox_4[x] = sbox_1[math.rotl(u8, x, 1)];
今回の実装ではSBOX2
からSBOX4
は事前に計算したものを使用しています。
FL関数とFLINV関数
FL関数とFLINV関数はhttps://datatracker.ietf.org/doc/html/rfc3713#section-2.4.2で説明されています。
テスト
https://datatracker.ietf.org/doc/html/rfc3713#appendix-Aにテストベクターがあるのでこれで正しく実装できたか検証できます。
また、https://info.isl.ntt.co.jp/crypt/eng/camellia/dl/cryptrec/t_camellia.txtにより大きなテストベクターがあります。
今回の実装ではこのテストベクターをYAMLにして、それをZigの標準ライブラリで読み取れるJSONに変換してテストしています。
終わりに
Zig以外のプログラミング言語でも上記のようにRFCに従ったコードを書くことでCamelliaを実装できます。
Zigは128ビット整数型がプリミティブ型なので他のプログラミング言語よりも簡単に実装できるように思いました。
Discussion