mixi engineer blog

*** 引っ越しました。最新の情報はこちら → https://medium.com/mixi-developers *** ミクシィ・グループで、実際に開発に携わっているエンジニア達が執筆している公式ブログです。様々なサービスの開発や運用を行っていく際に得た技術情報から採用情報まで、有益な情報を幅広く取り扱っています。

100% Pure JavaScript Camellia

NTTと三菱電機が共同開発した共通鍵ブロック暗号 "Camellia" の実装について以前調査していた時、ついカッとなってJavaScriptで実装してしまいました。類似の実装も既にあるようですし今は反省しているのですが、死蔵しておくのもナンなので晒しておきます。

ソースコードと使い方

小ネタなので、このソースコードはpublic domainということにしますね。

Public domain CryptoCipherCamellia-js-1.0.2

CryptoCipherCamellia.jsは128-bitブロック暗号Camelliaのプリミティブの実装と、暗号利用モードとしてCBCモードの実装を含んでいます。例を簡単に示すと次のような感じです:

var SECRET_KEY = CryptoUtil.arrayFromHex( 
    "00112233445566778899AABBCCDDEEFF"); 
var INITIAL_VECTOR = CryptoUtil.arrayFromHex( 
    "000102030405060708090A0B0C0D0E0F"); 
var PLAIN_TEXT = CryptoUtil.arrayFromString("Hello World!"); 

var engine = new CryptoCipherCamellia(); 
/* 暗号化 */ 
var cbc = new CryptoModeCBC(engine, SECRET_KEY, INITIAL_VECTOR); 
var cipherText = cbc.encrypt(PLAIN_TEXT); 
alert("Cipher Text(HEX): " + CryptoUtil.hexFromArray(cipherText)); 

/* 復号 */ 
cbc = new CryptoModeCBC(engine, SECRET_KEY, INITIAL_VECTOR); 
var plainText = cbc.decrypt(cipherText); 
alert("Plain Text: " + CryptoUtil.stringFromArray(plainText));

パッケージにはデモと単体テストとして

  • (無駄に)単体テスト
  • 16進数で入出力
  • Base64で入出力

を含んでいます。 ちなみに。(すごくおおざっぱな説明になりますが)Feistel構造をもつ暗号アルゴリズムであるCamelliaは、入力された128ビットのデータを前後半分64ビットずつに2分割して、

  1. 副鍵と置換表で片側のデータブロックを撹拌する
  2. 撹拌結果をもう片側のデータブロックとXORする

といった処理を64ビットのデータブロックを交互に入れ替えながらくり返して暗号化しています。これらの処理を一般的な計算機で実行する場合、普通はCPUに都合のよい32ビットや64ビット幅の整数を使って撹拌処理を実装します。しかしながらCryptoCipherCamellia.jsは、これまた私の気の迷いでわざわざ8ビット幅の整数で実装しています。さらに僕自身JavaScriptは遊びかそれ以前のレベルでしか書いていないので、作法やチューニングしどころがよくわかっていません故、モノスゴク遅いのでそこんとこよろしくです。 CamelliaそのものについてはNTT 情報流通プラットフォーム研究所のCamellia紹介仕様書 (PDF)などを参照してください。

カッとなったついでにPerl版

これまたついカッとなって書いてしまったのですが、同様にPerlだけで書いたCamelliaの実装 Crypt::Camellia_PPもこっそりCPANに上げていたりしますので、ネタとして遊んでみて頂けると幸いです。 Perl向けCamelliaの他の実装としては、XSで記述したCrypt::Camelliaがあります。こちらは当初Dan Kogaiさん書かれたモジュールですが、一年ほど前に小山がメンテナンスを引き継ぎました。実行速度はPure Perl版と比べて段違いに速いので、PerlでCamelliaを使いたい用件では普通にこちらを選んで頂けると幸いです。