SHA-1の高速化tips 2007/9/15 光成滋生@サイボウズ・ラボ.

Slides:



Advertisements
Similar presentations
第6回 JavaScript ゼミ セクション3-6 発表者 直江 宗紀. 組み込み関数  JavaScript に予め用意された関数  特定のオブジェクトに依存していない  単に関数名で呼び出すことが可能.
Advertisements

オブジェクト指向言語・ オブジェクト指向言語演習 中間試験回答例. Jan. 12, 2005 情報処理技術基礎演習 II 2 オブジェクト指向言語 中間試験解説 1  (1) 円柱の体積(円柱の体積 = 底面の円の面積 x 高さ) を求めるプログラムを作成しなさい。ただし、出力結果は、入 力した底面の円の半径.
モバイルエージェントシステムの実装 エージェント移動(状態とコードの一括移送) エージェント移動の特徴 システム構成 エージェントプログラム
プログラムのパタン演習 解説.
京都大学情報学研究科 通信情報システム専攻 湯淺研究室 M2 平石 拓
4.ソート 4-1.ソート問題について 4-2.簡単なソートアルゴリズム 4-3.高度なソートアルゴリズム
情報基礎演習B 後半第5回 担当 岩村 TA 谷本君.
ファーストイヤー・セミナーⅡ 第8回 データの入力.
実行時のメモリ構造(1) Jasminの基礎とフレーム内動作
Lightweight Language Weekend ls-lRシェル
基礎プログラミングおよび演習 第9回
LMNtalからC言語への変換の設計と実装
LMNtalからC言語への変換の設計と実装
ISD実習E 2009年6月1日 read関数 read-macro back-quote 文字列のread 課題
String - 文字列 2009年10月9日 7ADD2116 佐藤洋輔.
プログラミング論 II 電卓,逆ポーランド記法電卓
問題 1 キーボードから入力した数の合計を計算するプログラムを 作成せよ。最初に、何個の数を入力するかその数を入力 するようにする。
OSI7層の各層の1)名称 2)機能の簡単な説明 3)各階層に関連のあ る機器、規格などを5つ以上書いて下さい。
の まとめ 2007/04/02 (Mon) / d;id:hzkr
アルゴリズムとデータ構造 2011年6月20日
テキストボックス、チェックボックス×2、コマンドボタンを配置する。 コマンドボタンに機能を与える
第7回 条件による繰り返し.
細かい粒度でコードの再利用を可能とするメソッド内メソッドのJava言語への導入
ちょっとした練習問題① 配列iroを['R', 'W', 'R', 'R', 'W' , 'W' , 'W']を宣言して、「W」のときの配列の番号をprintfで表示するようなプログラムを記述しなさい。
アルゴリズムとデータ構造 2012年6月28日
アルゴリズムとデータ構造 2011年6月27日
関数とポインタ 値呼び出しと参照呼び出し swapのいろいろ 関数引数 数値積分
B演習(言語処理系演習)第8回 評価器 田浦.
プログラミング応用 printfと変数.
最適化の方法 中田育男著 コンパイラの構成と最適化 朝倉書店, 1999年 第11章.
EclipseでWekaのAPIを呼び出す
プログラミング演習I 2003年5月7日(第4回) 木村巌.
第7回 条件による繰り返し.
第7回 プログラミングⅡ 第7回
プログラミング言語論 第五回 理工学部 情報システム工学科 新田直也.
動的データ依存関係解析を用いた Javaプログラムスライス手法
第5回放送授業.
プログラミング基礎B 文字列の扱い.
一時的な型 長谷川啓
プログラミング 4 整列アルゴリズム.
2005年度 データ構造とアルゴリズム 第6回 「ハッシュ法を用いた探索」
アルゴリズム論 (第12回) 佐々木研(情報システム構築学講座) 講師 山田敬三
コンパイラ 2011年10月20日
プログラミング言語入門 2013 (C言語 初級) 演習期間 担当 参考資料 採点 10/24 - 1/23 (全10回) 松澤,鈴木,児玉
★C++/オブジェクト指向実践企画★ Othelloゲーム作成
参照されないリテラル 長谷川啓
データ構造とアルゴリズム (第5回) 静岡大学工学部 安藤和敏
IF文 START もしも宝くじが当たったら 就職活動する 就職活動しない YES END NO.
第6回レポート解説 条件1 条件2 条件3 月の入力 月、日、曜日の表示 日の入力 曜日の入力
情報基礎演習B 後半第2回 担当 岩村 TA 谷本君.
福井大学大学院工学研究科機械工学専攻 川谷 亮治
アルゴリズムとデータ構造1 2008年7月24日
アルゴリズムとデータ構造 2013年7月1日
アルゴリズムとデータ構造 --- 理論編 --- 山本 真基
オブジェクト指向言語論 第五回 知能情報学部 新田直也.
発表者: 稲葉 一浩 複雑ネットワーク・地図グラフ セミナー 2017/1/19
プログラミング基礎演習 第4回.
標準入出力、変数、演算子、エスケープシーケンス
オブジェクト指向 プログラミング 第四回 知能情報学部 新田直也.
情報処理Ⅱ 2007年12月3日(月) その1.
コンパイラ 2012年10月11日
アルゴリズムとデータ構造 2012年6月21日
プログラミング 4 文字列.
Inline 展開のアルゴリズム 長谷川啓
プログラミング入門2 第6回 関数 情報工学科 篠埜 功.
演算子のオーバーロード.
第7章 そろそろ int 以外も使ってみよう! ~データ型 double , bool~
プログラミング演習I 2003年6月11日(第9回) 木村巌.
知能情報工学演習I 第10回( C言語第4回) 課題の回答
プログラミング 2 静的変数.
Presentation transcript:

SHA-1の高速化tips 2007/9/15 光成滋生@サイボウズ・ラボ

目次 前置き 初級編 中級編 マニアック編 地道に速度を稼ぐ 自己書換えによるお気軽ループ/インライン展開 Firefoxの特性を使った高速化

前置き 高速化 以上,すべてyesなら次へ 本当に必要? プロファイルした? アルゴリズムの見直しは? メンテ大変だけどコストに見合う? 小手先技術はすぐ廃れるけど覚悟はいい? 以上,すべてyesなら次へ

初級編(1/6) Blowfishの暗号化コアを例に コアのリファレンス実装 : 8byte入力, 8byte出力 IE 6 Fx2.0 encCore : function(inp) { var xL = inp[0]; var xR = inp[1]; var tmp; for (var i = 0; i < this.N; i++) { xL ^= this.P[i]; xR ^= this.F(xL); tmp = xL; xL = xR; xR = tmp; } xR = xR ^ this.P[this.N]; xL = xL ^ this.P[this.N + 1]; if (xL < 0) xL += 4294967296; if (xR < 0) xR += 4294967296; return [xL, xR]; IE 6 Fx2.0 処理時間 134 162 高速化率 100% @PentiumD2.8GHz

初級編(2/6) 入出力を同一に function (inp) { return out; } → function(inout); encCore : function(inout) { var xL = inout[0]; var xR = inout[1]; var tmp; for (var i = 0; i < this.N; i++) { xL ^= this.P[i]; xR ^= this.F(xL); tmp = xL; xL = xR; xR = tmp; } xR = xR ^ this.P[this.N]; xL = xL ^ this.P[this.N + 1]; if (xL < 0) xL += 4294967296; if (xR < 0) xR += 4294967296; inout[0] = xL; inout[1] = xR; IE 6 Fx2.0 処理時間 134 155 高速化率 100% 104%

初級編(3/6) thisのalias作成 this.N → Nなど IE 6 Fx2.0 処理時間 128 155 高速化率 104% encCore : function(inout) { var xL = inout[0]; var xR = inout[1]; var tmp; var N = this.N, P = this.P; for (var i = 0; i < N; i++) { xL ^= P[i]; xR ^= this.F(xL); tmp = xL; xL = xR; xR = tmp; } xR = xR ^ P[N]; xL = xL ^ P[N + 1]; if (xL < 0) xL += 4294967296; if (xR < 0) xR += 4294967296; inout[0] = xL; inout[1] = xR; IE 6 Fx2.0 処理時間 128 155 高速化率 104%

初級編(4/6) 1回unloopによるswapの除去 block暗号化における常套手段 IE 6 Fx2.0 処理時間 126 153 encCore : function(inout) { var xL = inout[0]; var xR = inout[1]; var tmp; var N = this.N, P = this.P; for (var i = 0; i < N; i += 2) { xL ^= P[i]; xR ^= this.F(xL); xR ^= P[i + 1]; xL ^= this.F(xR); } xL = xL ^ P[N]; xR = xR ^ P[N + 1]; if (xL < 0) xL += 4294967296; if (xR < 0) xR += 4294967296; inout[0] = xR; inout[1] = xL; IE 6 Fx2.0 処理時間 126 153 高速化率 106%

初級編(5/6) 関数呼び出しを止める 速いけど汚い IE 6 Fx2.0 処理時間 73 129 高速化率 183% 125% for (var i = 0; i < N; i += 2) { var a, b, c, d, x, y; xL ^= P[i]; x = xL; d = x & 255; x >>>= 8; c = x & 255; x >>>= 8; b = x & 255; x >>>= 8; a = x & 255; y = ((S0[a] + S1[b]) ^ S2[c]) + S3[d]; xR ^= y; xR ^= P[i + 1]; x = xR; d = x & 255; x >>>= 8; xL ^= y; } IE 6 Fx2.0 処理時間 73 129 高速化率 183% 125%

初級編(6/6) ループ展開し,変数伝搬も修正 速いけど読めない でもどうしても速度が欲しいならありかも IE 6 Fx2.0 処理時間 var a, b, c, d, x, y; x = xL ^= P[9]; d = x & 255; x >>>= 8; c = x & 255; x >>>= 8; b = x & 255; x >>>= 8; a = x & 255; xR ^= ((S0[a] + S1[b]) ^ S2[c]) + S3[d]; x = xR ^= P[8]; xL ^= ((S0[a] + S1[b]) ^ S2[c]) + S3[d]; x = xL ^= P[7]; x = xR ^= P[6]; (中略) x = xR ^= P[4]; x = xL ^= P[3]; x = xR ^= P[2]; IE 6 Fx2.0 処理時間 53 103 高速化率 252% 157%

中級編(1/3) JavaScriptは関数もobject なら実行前に書き換えてみよう オリジナルアイデアは奥さん@labs.cybozu.co.jp var f = targetFunction.toString().split('\n'); 与えられた関数をtoString()で文字列にする 文字列を解析し書き換える eval()を使って関数を定義し直す これらを起動時に一度呼ぶ

中級編(2/3) 作ってみた これらを起動時に一度呼ぶ まじめなJavaScriptパーサは大変なので超限定版 unrollLoop(出力関数, 入力関数); 与えられた関数内のforループを展開する関数 forceInline(出力関数, 入力関数, 展開関数); 与えられた関数が呼び出す関数を展開する関数 これらを起動時に一度呼ぶ optimize()

中級編(3/3) ベンチマーク 下記コードに1行加えるだけ optimize('encCore2', encCore, 'this.F'); encCore : function(inout) { var xL = inout[0]; var xR = inout[1]; var tmp; var N = this.N, P = this.P; for (var i = 0; i < N; i += 2) { xL ^= P[i]; xR ^= this.F(xL); xR ^= P[i + 1]; xL ^= this.F(xR); } xL = xL ^ P[N]; xR = xR ^ P[N + 1]; if (xL < 0) xL += 4294967296; if (xR < 0) xR += 4294967296; inout[0] = xR; inout[1] = xL; IE 6 Fx2.0 処理時間 126 153 手動最速 53 103 IE 6 Fx2.0 処理時間 73 101 いい線 互角

マニアック編(1/3) ところでFxはIEの50~70%の速度しか出ない? 現象 block暗号,ハッシュ関数系の処理では似た傾向 countが小さいときはFxも速い var x = 0; var count = 1000000; for (var i = 0; i < count; i++) { x += i; }

マニアック編(2/3) 原因はFxのSTORE_INT()の実装にあり 絶対値が2^30-1を超える数値にはメモリ確保が伴う 大抵のLLの実装では整数を効率よく扱うために32bitのうち1bitを判別フラグに利用している IEは違うようだ if (INT_FITS_IN_JSVAL(i)) { v_ = INT_TO_JSVAL(i); } else { ok = js_NewDoubleValue(cx, (jsdouble)(i), &v_); if (!ok) goto out; }

マニアック編(3/3) 解決方法 例(x ^ y) 詳細は 32bit変数を16bit x 2として扱い, 最大値が2^30にならないように実装する これでFxでSHA-1をIEなみの速度にもっていける ただしコードは本当に読めない(^^; 例(x ^ y) x = [xH:xL], y = [yH:yL] として xH ^ yH, xL ^ yL を計算する 詳細は http://labs.cybozu.co.jp/blog/mitsunari/