Presentation is loading. Please wait.

Presentation is loading. Please wait.

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

Similar presentations


Presentation on theme: "SHA-1の高速化tips 2007/9/15 光成滋生@サイボウズ・ラボ."— Presentation transcript:

1 SHA-1の高速化tips 2007/9/15

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

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

4 初級編(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 += ; if (xR < 0) xR += ; return [xL, xR]; IE 6 Fx2.0 処理時間 134 162 高速化率 100% @PentiumD2.8GHz

5 初級編(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 += ; if (xR < 0) xR += ; inout[0] = xL; inout[1] = xR; IE 6 Fx2.0 処理時間 134 155 高速化率 100% 104%

6 初級編(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 += ; if (xR < 0) xR += ; inout[0] = xL; inout[1] = xR; IE 6 Fx2.0 処理時間 128 155 高速化率 104%

7 初級編(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 += ; if (xR < 0) xR += ; inout[0] = xR; inout[1] = xL; IE 6 Fx2.0 処理時間 126 153 高速化率 106%

8 初級編(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%

9 初級編(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%

10 中級編(1/3) JavaScriptは関数もobject
なら実行前に書き換えてみよう var f = targetFunction.toString().split('\n'); 与えられた関数をtoString()で文字列にする 文字列を解析し書き換える eval()を使って関数を定義し直す これらを起動時に一度呼ぶ

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

12 中級編(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 += ; if (xR < 0) xR += ; inout[0] = xR; inout[1] = xL; IE 6 Fx2.0 処理時間 126 153 手動最速 53 103 IE 6 Fx2.0 処理時間 73 101 いい線 互角

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

14 マニアック編(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; }

15 マニアック編(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 を計算する 詳細は


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

Similar presentations


Ads by Google