SlideShare ist ein Scribd-Unternehmen logo
1 von 28
Downloaden Sie, um offline zu lesen
Optimal Ateペアリングの
実装詳細
2013/7/3
サイボウズ・ラボ
光成滋生
目次
 Optimal Ateペアリングの定義(さらっと)
 今回はペアリングの話ではなく最適化全般のトピックが主
 x64 CPUの概略
 実行時間の計測
 整数加算、減算の実装
 整数乗算の実装
 Haswell向けの改良
 その他のトピック
/ 282
BN曲線
 𝐹𝑝上で定義される埋め込み次数12の楕円曲線
 𝐸: 𝑦2 = 𝑥3 + 𝑏, 𝑏 ∈ 𝐹𝑝
 𝑝 ≔ 𝑝 𝑧 = 36𝑧4
+ 36𝑧3
+ 24𝑧2
+ 6𝑧 + 1
𝑧が64bitなら𝑝は256bitぐらいの素数
 𝑟 ≔ 𝑟 𝑧 = 36𝑧4 + 36𝑧3 + 18𝑧2 + 6𝑧 + 1
 𝑡 ≔ 𝑡 𝑧 = 6𝑧2 + 1
 #𝐸(𝐹𝑝) = 𝑟
/ 283
記号
 𝜋: 𝑥, 𝑦 → 𝑥 𝑝
, 𝑦 𝑝
 Frobenius写像
 BN曲線に対してはtrace(𝜋 𝑝) = 𝑡
 𝑓𝑠,𝑄: 𝐸上の有理関数(𝑠は整数𝑄は𝐸上の点)
 div 𝑓𝑠,𝑄 = 𝑠 𝑄 − 𝑠 𝑄 − 𝑠 − 1 𝒪 を満たすもの
𝑠 𝑄 は 𝑄 の形式的な𝑠倍、 𝑠 𝑄は𝑄の 𝑠 倍された点を意味する
 𝑙 𝑄1,𝑄2
 𝑄1と𝑄2を通る直線
/ 284
Optimal Ateペアリング
 𝐺1 = 𝐸 𝑟 ∩ ker 𝜋 𝑝 − 1 = 𝐸 𝐹𝑝 𝑟
 𝐺2 = 𝐸 𝑟 ∩ ker 𝜋 𝑝 − 𝑝 ⊆ 𝐸 𝐹𝑝
12
𝑟
 𝐺3 = 𝜇 𝑟 ⊂ 𝐹𝑝
12 ∗
 𝑒 ∶ 𝐺2 × 𝐺1 ∋ 𝑄, 𝑃 ⟼ 𝑚 𝑄, 𝑃
𝑝12−1
𝑟 ∈ 𝐺3
 𝑚 𝑄, 𝑃 ∶= 𝑓6𝑧+2,𝑄 𝑃 ∙ 𝑔 𝑄 𝑃
 𝑔 𝑄(𝑃) ≔ 𝑙 6𝑧+2 𝑄,𝜋 𝑝 𝑄 𝑃 ∙ 𝑙 6𝑧+2 𝑄+𝜋 𝑝 𝑄 ,−𝜋 𝑝
2 𝑄 (𝑃)
/ 285
ペアリングのアルゴリズム
 1) 6𝑧 + 2 𝑄 と 𝑓6𝑧+2,𝑄 𝑃 を算出(Millerループ)
 2) 𝑚 𝑄, 𝑃 = 𝑓6𝑧+2,𝑄 𝑃 ∙ 𝑔 𝑄 𝑃 を算出
 3)
𝑝12−1
𝑟
乗する(最終巾)
/ 286
拡大体上の演算における戦略
 𝐹 𝑝2上の乗算
 x=a+bu, y = c+du, u^2 = -1
 xy = (ac – bd) + ((a+b)(c+d) – ac – bd)u
 従来
 ac, bd, (a+b)(c+d)はFp:mulを使う
 Pairing2010における主要アイデア
 Fp:mul = mul256 + mod512
mul256 : 256ビット整数乗算mul256
 64bit乗算命令は速い(3clk, latency, 1clk throughput)
mod512 : Montgomeryリダクション
 mul256の結果に対する加減算
ac, bd, (a+b)(c+d)を512bit整数のまま加減算
mod512の回数が3回から2回になる
 512bit加減算は増える / 287
Aranhaらによる改良
 𝐹 𝑝6などの拡大体にも容易に適用可能
 拡大体の係数もより小さいものに
 𝑏 = 2, z = −(262 + 255 + 1)
 𝐹 𝑝2 = 𝐹𝑝 U / U2 − 𝛽 , 𝛽 = −1 ∈ 𝐹𝑝
 𝐹 𝑝6 = 𝐹 𝑝2 V / V3
− 𝜉 , 𝜉 = 1 + U ∈ 𝐹 𝑝2
 𝐹 𝑝12 = 𝐹 𝑝6 W / W2 − V , 𝛾 = 𝑉 ∈ 𝐹 𝑝6
 実装
 最新の実装は上記を踏襲し,細部を改良
 https://github.com/herumi/ate-pairing/
0.35msec@Haswell(i7-4700MQ 3.4GHz)
/ 288
x64 CPU概略
 15個の汎用64bitレジスタ
 rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, ..., r15
 フラグレジスタ
 演算結果に応じて変わる1bitの情報群
CF : 加算時に結果が64bitを超えた、減算でマイナスになった
ZF : 結果が0になった
SF : 結果の最上位ビットが1だった
 呼び出し規約
 関数の引数に対応するレジスタ名
WindowsとLinuxで異なる
 Windows : rcx, rdx, r8, r9
 Linux : rdi, rsi, rdx, rcx
 関数の中で壊してよいものと元に戻す必要のあるもの
Linux : r12, ..., r15, rbx, rbp, Win : 加えてrsi, rdi
/ 289
算術演算
 加減算
 add x, y // x ← x + y;
 sub x, y // x ← x – y;
 carryつき加減算
 adc x, y // x ← x + y + CF; 繰り上がりを加味
 sbb x, y // x ← x – y – CF; 繰り下がりを加味
 乗算
 64bit x 64bit → 128bit
 mul x // [rdx:rax] ← x * rax (rax, rdxレジスタ固定)
 除算
 128bit / 64bit = 64bit あまり 64bit
 div x // [rdx:rax] / x ; 商 : rax, あまり : rdx
/ 2810
条件比較
 演算結果に応じてフラグが変わる
 フラグに応じて条件分岐する
 こういうコードはこんな感じ
 jg (jmp if greater), jge(jmp if greater or equal)などなど
/ 2811
if (x >= y) {
Aの作業
} else {
Bの作業
}
cmp x, y // x-yの計算結果をCFに反映(CF = x >= y ? 0 : 1)
jnc LABEL_A // jmp to LABEL_A if no carry
Bの作業
jmp NEXT
LABEL_A:
Aの作業
NEXT:
アセンブラの種類
 gas, NASM, MASMなど
 静的なアセンブラ
 マクロや条件式などの文法はそれぞれ独自構文
 inline assembler
 おもにgcc(64bit Visual Studioでは非サポート)
 コンパイラが多少最適化してくれることも
 記述が難しい
 LLVM
 抽象度の高いアセンブラ/JIT可能
 carryの扱いが難しく今回の用途では性能を出しにくい
 Xbyak(拙作)
 抽象度は低い(gasやNASMと同じ)/JIT可能
 C++の文法でアセンブラをかける
/ 2812
実行時間の測り方
 Vtune(Intel), CodeAnalyst(AMD)など
 CodeAnalystは無料
Intel CPUでも使える
 perfコマンド(Linux only)
 perf listで測定したいパラメータを表示
instructions
branch-missessなどCPUによって様々なものがある
 perf stat –e L1-icache-load-misses 実行コマンド
/ 2813
rdtsc
 CPUがもつカウンタ
 (2.8GHzなら1/2.8 nsec単位で)一つずつ増える
 Turboboostは切った方が周波数が固定になってよい
駄目なら重たい処理を先に実行させてトップスピードにさせる
 マルチプロセス向けにrdtscpというのもある
 Xbyakではrdtscの薄いラッパークラスClockを提供
 clk.begin(), clk.end()で測定したい関数をはさむ
 最後にclk.getClock() / clk.getCount()で平均値を取得
/ 2814
Xbyak::util::Clock clk;
for (int i = 0;i < N; i++) {
clk.begin();
some_function();
clk.end();
}
printf("%.2fclk¥n", clk.getClock() / double(clk.getCount()));
256bit加算
 記法
 xi, yi, ziなどは64bitレジスタを表す
 [x3:x2:x1:x0]で256bit整数を表す(x0が最下位の64bit)
 256bit整数z[]に256bit整数x[]を足すコードは次の通り
 注意
 z[], x[]が256bitフルに入ってると結果が257bitになる
 今回はpを254bitに選んだため0 <= x, z < pならあふれない
他にも様々な箇所で桁あふれがおきないため処理の簡略化が可能
そのためセキュリティレベルが128bitではなく127bit
/ 2815
// [z3:z2:z1:z0] += [x3:x2:x1:x0]
add z0, x0
adc z1, x1 // carryつき
adc z2, x2 // carryつき
adc z3, x3 // carryつき
256bit加算を関数にする
 呼び出し規約にしたがってレジスタを使う
 なかなか面倒
 XbyakのStackFrameを使うとある程度抽象化、自動化可能
LLVMはより汎用的にできる
/ 2816
//addNC(uint64_t z[4],const uint64_t x[4],const uint64_t y[4]);
void gen_AddNC() {
Xbyak::util::StackFrame sf(this, 3); //引数3個の関数
const Xbyak::Reg64& z = sf.p[0]; // 一つ目の引数
const Xbyak::Reg64& x = sf.p[1]; // 二つ目の引数
const Xbyak::Reg64& y = sf.p[2]; // 三つ目の引数
mov(rax, ptr [x]);
add(rax, ptr [y]);
mov(ptr [z], rax);
for (int i = 1; i < 3; i++) {
mov(rax, ptr [x + i * 8]);
adc(rax, ptr [y + i * 8]);
mov(ptr [z + i * 8], rax);
} }
gen_addNCの結果
 WindowsとLinuxのそれぞれに応じたコード生成
 StackFrameはスタックを確保したり一時変数を使ったり、
rcx, rdxを特別扱いする指定もできる
自動的にレジスタの退避復元をおこなう
/ 2817
// Windows(引数はrcx,rdx,r8の順)
mov rax,ptr [rdx]
add rax,ptr [r8]
mov ptr [rcx],rax
mov rax,ptr [rdx+8]
adc rax,ptr [r8+8]
mov ptr [rcx+8],rax
mov rax,ptr [rdx+10h]
adc rax,ptr [r8+10h]
mov ptr [rcx+10h],rax
ret
// Linux(引数はrdi,rsi,rdxの順)
mov rax,ptr [rsi]
add rax,ptr [rdx]
mov ptr [rdi],rax
mov rax,ptr [rsi+0x8]
adc rax,ptr [rdx+0x8]
mov ptr [rdi+0x8],rax
mov rax,ptr [rsi+0x10]
adc rax,ptr [rdx+0x10]
mov ptr [rdi+0x10],rax
ret
Fp::addの実装
 addNCした結果zがz>=pならばpを引く
 if (z >= p) z -= p;
 アセンブラレベルでの比較の方法
 z=[z3:z2:z1:z0]とx=[x3:x2:x1:x0]はどちらが大きいか
 1. 頭から比較する
 分岐がきわめて多くなる
連続する分岐命令は好まれない
 2. 引いてから考える
 分岐は1回
/ 2818
cmp z3, x3
ja z_gt_x // z3 > x3
jb otherwise // z3 < x3
cmp z2, x2 // here z3 == x3
ja z_gt_x // z2 > x2
jb otherwise // z2 < x2
...
z_gt_x:
...
otherwise:tmp_z = z // zの値を退避(mov x 4)
subNC z, p // 引いてみる(z -= p)
jnc .next // z >= 0ならnextへ
z = tmp_z // zの値を復元(mov x 4)
.next:
分岐しないFp::addの実装
 CPUは分岐予測をする
 当たると大体1clk
 外れると大体20clk
 一般のデータでは偏りがあるので結構精度よく当たる
 が、今回はランダムなので的中率は50%→平均10clk
 分岐予測を排除する
 条件移動命令cmovXX
2clk latency
1clk thrgouthput
 addの二つの実装 分岐あり1.39Mclk, 分岐なし1.35Mclk
もちろんCPUによって異なる可能性あり(sandy, ivyで効果あり)
単純ベンチだと分岐予測があたって分岐あり版が速くみえるかも
/ 2819
mov ti, zi x 4
subNC z, p
cmovc zi, ti ; 引きすぎてたら戻す
Fp::subの実装
 subNCした結果が負ならpを足す
 addと違ってsubNCした時のCFを見ればよいので比較不要
 分岐を使った実装
 cmovを使った実装
 0クリア
 cmov + メモリロード
 加算
結構命令数が多いので分岐に対してそれほどメリットがない
 cmovを使わない実装
 命令数は同じだが
cmovよりは速い@sandy
/ 2820
// z -= xの直後
jnc .next
z[] += p[]
.next:
t[] = 0
cmovc t[] p[] //t[] = CF ? p[0] : 0
z[] += t[]
sbb t, t // t = CF ? -1 : 0
and t[], p[] // t = CF ? p : 0
z[] += t[]
256ビット加減算の命令順序
 メモリから読んで演算する二つの方式
 方式A(メモリまとめ読み) 方式B(メモリと演算を交互に)
 実験によるとどちらが速いかCPUにより異なる
Opteron, i7は方式Aが速い Westmereは方式Bが速かった
 out of orderだから関係ないと思ったが1%弱違った
 実行時のCPU判別によりいずれかを選択
上記方式はコード全般にわたって適用される
/ 2821
z0 ← x[0]
z1 ← x[1]
z2 ← x[2]
z3 ← x[3]
z0 ← z0 + y[0]
z1 ← z1 + y[1] with carry
z2 ← z2 + y[2] with carry
z3 ← z3 + y[3] with carry
z0 ← x[0]
z0 ← z0 + y[0]
z1 ← x[1]
z1 ← z1 + y[1] with carry
z2 ← x[2]
z2 ← z2 + y[2] with carry
z3 ← x[3]
z3 ← z3 + y[3] with carry
256ビットx256ビット乗算(1/2)
 256ビット整数を64ビット整数4個の組で表現する
 64ビット→320ビット乗算4回と320ビット加算3回
 筆算方式でmulするごとにaddを行う
繰り上がり加算が3回余計に増える
/ 2822
𝑥3 𝑥2 𝑥1 𝑥0
𝑦
𝑥0 𝑦
𝑥1 𝑦
+
+(繰り上がり)
𝑥2 𝑦
+
+(繰り上がり)
・・・
1. 𝑥0 𝑦を計算
2. 𝑥1 𝑦を計算
3. 𝑥0 𝑦 𝐿 + 𝑥1 𝑦 𝐻
t0 = 𝑥1 𝑦 𝐻 + 𝑐𝑎𝑟𝑟𝑦
4. 𝑥2 𝑦を計算
5. 𝑥2 𝑦 𝐿 + 𝑡0
𝑡1 = 𝑥2 𝑦 𝐻 + 𝑐𝑎𝑟𝑟𝑦
6. ...
256ビットx256ビット乗算(2/2)
 乗算4回してから加算すると余計な加算が不要
 ただし乗算結果を保持するワークエリアが必要
 mulがCFを変更するためadcと同時に使えない
 15個のレジスタを使い回して一時メモリを使わずに実装
/ 2823
1. [𝑥𝑖 𝑦](𝑖 = 0 … 3)を計算
2. それらをまとめて加算
↓
加算は4回
𝑥3 𝑥2 𝑥1 𝑥0
𝑦
𝑥0 𝑦
𝑥1 𝑦
𝑥2 𝑦
𝑥3 𝑦
加算が終わるまでどこかに
保持する必要がある
256ビットx256ビット乗算 for Haswell
 HaswellではCFを変更しないmulxが導入された
 加算(add, adc)しつつ乗算を繰り返しおこなえる
 必要なレジスタ数が減る
 退避、復元のためのmov命令が減る
 Montgomery reductionにも適用可能
 ペアリング全体で13%の高速化
 1.33Mclkから1.17Mclkへ(@Core i7 4700MQ 2.4GHz)
/ 2824
mov(a, ptr [py]); | ↓
mul(x); | mul(x);
mov(t0, a); | mov(t3, a);
mov(t1, d); | mov(a, x);
mov(a, ptr [py + 8]); | mov(x, d);
mul(x); | mul(qword [py + 24]);
mov(t, a); | add(t1, t);
mov(t2, d); | adc(t2, t3);
mov(a, ptr [py + 16]);| adc(x, a);
↓ | adc(d, 0);
mov(d, x);
mulx(t1, t0, ptr [py]);
mulx(t2, a, ptr [py + 8]);
add(t1, a);
mulx(x, a, ptr [py + 16]);
adc(t2, a);
mulx(d, a, ptr [py + 24]);
adc(x, a);
adc(d, 0);
記述の簡便さのための手法
 各種2項演算はsrc x 2 + dstのglobal関数を作る
 Fp::add(z, x, y); // z = x + yなど
 &z == &x == &yなどのときでも正しく動くように注意
 演算子オーバーロード
 Fp operator+(const Fp&, const Fp&)などをFp::addを使
って定義する
z = x + y;などとかける。
 Fp2, Fp6, Fp12などの拡大体でも同様に作る
 コピペばかりになって間違いやすい
/ 2825
CRTPによる半自動的生成手法
 add, subなどを使ってoperator+, operator-を定義
するtemplateクラス
 Fp, Fp2などはadd, subさえつくればaddsubmulを
継承することでoperator+が使えるようになる
 virtual継承ではないので呼び出し時のコストは(通常)ない
/ 2826
template<class T, class E = Empty<T> >
struct addsubmul : E {
template<class N>
T& operator+=(const N& rhs) {
T::add(static_cast<T&>(*this), static_cast<T&>(*this), rhs);
return static_cast<T&>(*this); }
...
strut Fp : addsubmul<Fp>{
static void add(Fp&, const Fp&, const Fp&);
};
記法の簡便さと演算性能
 z = x + y;とFp::add(z, x, y);
 一般的に前者の方が書きやすく可読性も高い
 しかし隠れた一時変数の生成とコピーに注意する
 x + yの結果をtmpに保存
してz = tmpを実行
 方針
 最初は数式を書きやすい
前者で始める
 動くことがわかったら
一時変数や移動を減らす
ように後者に置き換える
式Templateによる一時変数
除去テクニックはあるが
正直使いにくい、挙動を
把握しにくいため勧めない
/ 2827
// Fp::add(z, x, y);
lea r8,[y]
lea rdx,[x]
lea rcx,[z]
call [mie::Fp::add]
// z = x + y;
lea r8,[rbp+7]
lea rdx,[rbp-19h]
lea rcx,[rbp-39h]
call [mie::Fp::add]
movaps xmm0,[rbp-39h] //データ移動
movaps [rbp+37h],xmm0
movaps xmm1,[rbp-29h]
movaps [rbp+47h],xmm1
 Fp6などの演算は基礎体のmulやaddを呼び出す
 mulはレジスタをフルに使うため関数の中でレジスタの退避
と復元をおこなっている
 連続してmulを呼び出すならその間の復元と退避は除去可能
 退避復元をしない専用関数を用意する
呼び出し規約からの逸脱
 コンパイラの関知しないところのため手作業が必要
LLVMがこの分野で使えるならoptに任せることも可能になるか
 メリット
 速度向上
 デメリット
 デバッグが難しい
かもしれない
Fp2_mul:
call Fp_mul
call Fp_mul
ret
Fp_mul:
レジスタの退避
本体
レジスタの復元
レジスタの退避・復元の省略の一般論
/ 2828
Fp2_mul:
call in_Fp_mul
call in_Fp_mul
ret
// Cからは呼べない
in_Fp_mul:
本体

Weitere ähnliche Inhalte

Was ist angesagt?

圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナドYoshihiro Mizoguchi
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装MITSUNARI Shigeo
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺MITSUNARI Shigeo
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回Tomoya Kawanishi
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門Fixstars Corporation
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~Takuya Akiba
 
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015CODE BLUE
 
自動定理証明の紹介
自動定理証明の紹介自動定理証明の紹介
自動定理証明の紹介Masahiro Sakai
 
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズムTakuya Akiba
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介MITSUNARI Shigeo
 
楕円曲線入門 トーラスと楕円曲線のつながり
楕円曲線入門トーラスと楕円曲線のつながり楕円曲線入門トーラスと楕円曲線のつながり
楕円曲線入門 トーラスと楕円曲線のつながりMITSUNARI Shigeo
 
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)Kensuke Otsuki
 
秘密分散法の数理
秘密分散法の数理秘密分散法の数理
秘密分散法の数理Akito Tabira
 
第11回 配信講義 計算科学技術特論A(2021)
第11回 配信講義 計算科学技術特論A(2021)第11回 配信講義 計算科学技術特論A(2021)
第11回 配信講義 計算科学技術特論A(2021)RCCSRENKEI
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexprGenya Murakami
 
様々な全域木問題
様々な全域木問題様々な全域木問題
様々な全域木問題tmaehara
 

Was ist angesagt? (20)

圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド圏論のモナドとHaskellのモナド
圏論のモナドとHaskellのモナド
 
WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装WebAssembly向け多倍長演算の実装
WebAssembly向け多倍長演算の実装
 
Xbyakの紹介とその周辺
Xbyakの紹介とその周辺Xbyakの紹介とその周辺
Xbyakの紹介とその周辺
 
きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回きつねさんでもわかるLlvm読書会 第2回
きつねさんでもわかるLlvm読書会 第2回
 
ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門ARM CPUにおけるSIMDを用いた高速計算入門
ARM CPUにおけるSIMDを用いた高速計算入門
 
プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~プログラミングコンテストでのデータ構造 2 ~動的木編~
プログラミングコンテストでのデータ構造 2 ~動的木編~
 
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
Master Canary Forging: 新しいスタックカナリア回避手法の提案 by 小池 悠生 - CODE BLUE 2015
 
自動定理証明の紹介
自動定理証明の紹介自動定理証明の紹介
自動定理証明の紹介
 
平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム平面グラフと交通ネットワークのアルゴリズム
平面グラフと交通ネットワークのアルゴリズム
 
SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介SSE4.2の文字列処理命令の紹介
SSE4.2の文字列処理命令の紹介
 
暗認本読書会7
暗認本読書会7暗認本読書会7
暗認本読書会7
 
楕円曲線入門 トーラスと楕円曲線のつながり
楕円曲線入門トーラスと楕円曲線のつながり楕円曲線入門トーラスと楕円曲線のつながり
楕円曲線入門 トーラスと楕円曲線のつながり
 
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
区間分割の仕方を最適化する動的計画法 (JOI 2021 夏季セミナー)
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
秘密分散法の数理
秘密分散法の数理秘密分散法の数理
秘密分散法の数理
 
第11回 配信講義 計算科学技術特論A(2021)
第11回 配信講義 計算科学技術特論A(2021)第11回 配信講義 計算科学技術特論A(2021)
第11回 配信講義 計算科学技術特論A(2021)
 
プログラムを高速化する話
プログラムを高速化する話プログラムを高速化する話
プログラムを高速化する話
 
中3女子でもわかる constexpr
中3女子でもわかる constexpr中3女子でもわかる constexpr
中3女子でもわかる constexpr
 
様々な全域木問題
様々な全域木問題様々な全域木問題
様々な全域木問題
 
最大流 (max flow)
最大流 (max flow)最大流 (max flow)
最大流 (max flow)
 

Ähnlich wie optimal Ate pairing

条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxpsMITSUNARI Shigeo
 
CUDA1日(?)体験会
CUDA1日(?)体験会CUDA1日(?)体験会
CUDA1日(?)体験会RinKuriyama
 
CUDA1日(?)体験会 (再アップロード)
CUDA1日(?)体験会 (再アップロード)CUDA1日(?)体験会 (再アップロード)
CUDA1日(?)体験会 (再アップロード)RinKuriyama
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチMasami Ichikawa
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介MITSUNARI Shigeo
 
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenIntel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenMITSUNARI Shigeo
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) 智啓 出川
 
あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)たけおか しょうぞう
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLakirahiguchi
 
文献紹介:Learnable Gated Temporal Shift Module for Free-form Video Inpainting
文献紹介:Learnable Gated Temporal Shift Module for Free-form Video Inpainting文献紹介:Learnable Gated Temporal Shift Module for Free-form Video Inpainting
文献紹介:Learnable Gated Temporal Shift Module for Free-form Video InpaintingToru Tamaki
 
Spmv9forpublic
Spmv9forpublicSpmv9forpublic
Spmv9forpublicT2C_
 
1072: アプリケーション開発を加速するCUDAライブラリ
1072: アプリケーション開発を加速するCUDAライブラリ1072: アプリケーション開発を加速するCUDAライブラリ
1072: アプリケーション開発を加速するCUDAライブラリNVIDIA Japan
 
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) 智啓 出川
 
Wavelet matrix implementation
Wavelet matrix implementationWavelet matrix implementation
Wavelet matrix implementationMITSUNARI Shigeo
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)Takeshi Yamamuro
 
並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.jsYoshiiro Ueno
 

Ähnlich wie optimal Ate pairing (20)

条件分岐とcmovとmaxps
条件分岐とcmovとmaxps条件分岐とcmovとmaxps
条件分岐とcmovとmaxps
 
フラグを愛でる
フラグを愛でるフラグを愛でる
フラグを愛でる
 
CUDA1日(?)体験会
CUDA1日(?)体験会CUDA1日(?)体験会
CUDA1日(?)体験会
 
CUDA1日(?)体験会 (再アップロード)
CUDA1日(?)体験会 (再アップロード)CUDA1日(?)体験会 (再アップロード)
CUDA1日(?)体験会 (再アップロード)
 
x86とコンテキストスイッチ
x86とコンテキストスイッチx86とコンテキストスイッチ
x86とコンテキストスイッチ
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介
 
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgenIntel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
Intel AVX-512/富岳SVE用SIMDコード生成ライブラリsimdgen
 
TVM の紹介
TVM の紹介TVM の紹介
TVM の紹介
 
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE) GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
GPGPU Seminar (GPU Accelerated Libraries, 2 of 3, cuSPARSE)
 
あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)あるRISC-V CPUの 浮動小数点数(異常なし)
あるRISC-V CPUの 浮動小数点数(異常なし)
 
HandlerSocket plugin for MySQL
HandlerSocket plugin for MySQLHandlerSocket plugin for MySQL
HandlerSocket plugin for MySQL
 
文献紹介:Learnable Gated Temporal Shift Module for Free-form Video Inpainting
文献紹介:Learnable Gated Temporal Shift Module for Free-form Video Inpainting文献紹介:Learnable Gated Temporal Shift Module for Free-form Video Inpainting
文献紹介:Learnable Gated Temporal Shift Module for Free-form Video Inpainting
 
HPC Phys-20201203
HPC Phys-20201203HPC Phys-20201203
HPC Phys-20201203
 
Spmv9forpublic
Spmv9forpublicSpmv9forpublic
Spmv9forpublic
 
M1 gp_Disco
M1 gp_DiscoM1 gp_Disco
M1 gp_Disco
 
1072: アプリケーション開発を加速するCUDAライブラリ
1072: アプリケーション開発を加速するCUDAライブラリ1072: アプリケーション開発を加速するCUDAライブラリ
1072: アプリケーション開発を加速するCUDAライブラリ
 
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust) GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
GPGPU Seminar (GPU Accelerated Libraries, 3 of 3, Thrust)
 
Wavelet matrix implementation
Wavelet matrix implementationWavelet matrix implementation
Wavelet matrix implementation
 
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
LLVMで遊ぶ(整数圧縮とか、x86向けの自動ベクトル化とか)
 
並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js並列対決 Elixir × Go × C# x Scala , Node.js
並列対決 Elixir × Go × C# x Scala , Node.js
 

Mehr von MITSUNARI Shigeo

暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学MITSUNARI Shigeo
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコルMITSUNARI Shigeo
 
暗認本読書会13 advanced
暗認本読書会13 advanced暗認本読書会13 advanced
暗認本読書会13 advancedMITSUNARI Shigeo
 
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法MITSUNARI Shigeo
 
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化MITSUNARI Shigeo
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用MITSUNARI Shigeo
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介MITSUNARI Shigeo
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたMITSUNARI Shigeo
 
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用MITSUNARI Shigeo
 

Mehr von MITSUNARI Shigeo (20)

暗号技術の実装と数学
暗号技術の実装と数学暗号技術の実装と数学
暗号技術の実装と数学
 
範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル範囲証明つき準同型暗号とその対話的プロトコル
範囲証明つき準同型暗号とその対話的プロトコル
 
暗認本読書会13 advanced
暗認本読書会13 advanced暗認本読書会13 advanced
暗認本読書会13 advanced
 
暗認本読書会12
暗認本読書会12暗認本読書会12
暗認本読書会12
 
暗認本読書会11
暗認本読書会11暗認本読書会11
暗認本読書会11
 
暗認本読書会10
暗認本読書会10暗認本読書会10
暗認本読書会10
 
暗認本読書会9
暗認本読書会9暗認本読書会9
暗認本読書会9
 
暗認本読書会8
暗認本読書会8暗認本読書会8
暗認本読書会8
 
暗認本読書会6
暗認本読書会6暗認本読書会6
暗認本読書会6
 
暗認本読書会5
暗認本読書会5暗認本読書会5
暗認本読書会5
 
暗認本読書会4
暗認本読書会4暗認本読書会4
暗認本読書会4
 
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
深層学習フレームワークにおけるIntel CPU/富岳向け最適化法
 
私とOSSの25年
私とOSSの25年私とOSSの25年
私とOSSの25年
 
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
Lifted-ElGamal暗号を用いた任意関数演算の二者間秘密計算プロトコルのmaliciousモデルにおける効率化
 
楕円曲線と暗号
楕円曲線と暗号楕円曲線と暗号
楕円曲線と暗号
 
BLS署名の実装とその応用
BLS署名の実装とその応用BLS署名の実装とその応用
BLS署名の実装とその応用
 
LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介LazyFP vulnerabilityの紹介
LazyFP vulnerabilityの紹介
 
Intro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみたIntro to SVE 富岳のA64FXを触ってみた
Intro to SVE 富岳のA64FXを触ってみた
 
ゆるバグ
ゆるバグゆるバグ
ゆるバグ
 
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
ElGamal型暗号文に対する任意関数演算・再暗号化の二者間秘密計算プロトコルとその応用
 

Kürzlich hochgeladen

CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?akihisamiyanaga1
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)UEHARA, Tetsutaro
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案sugiuralab
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)Hiroshi Tomioka
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...博三 太田
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineerYuki Kikuchi
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfFumieNakayama
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfFumieNakayama
 

Kürzlich hochgeladen (8)

CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
CTO, VPoE, テックリードなどリーダーポジションに登用したくなるのはどんな人材か?
 
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
デジタル・フォレンジックの最新動向(2024年4月27日情洛会総会特別講演スライド)
 
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
TataPixel: 畳の異方性を利用した切り替え可能なディスプレイの提案
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察  ~Text-to-MusicとText-To-ImageかつImage-to-Music...
モーダル間の変換後の一致性とジャンル表を用いた解釈可能性の考察 ~Text-to-MusicとText-To-ImageかつImage-to-Music...
 
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
自分史上一番早い2024振り返り〜コロナ後、仕事は通常ペースに戻ったか〜 by IoT fullstack engineer
 
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdfAWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
AWS の OpenShift サービス (ROSA) を使った OpenShift Virtualizationの始め方.pdf
 
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdfクラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
クラウドネイティブなサーバー仮想化基盤 - OpenShift Virtualization.pdf
 

optimal Ate pairing

  • 2. 目次  Optimal Ateペアリングの定義(さらっと)  今回はペアリングの話ではなく最適化全般のトピックが主  x64 CPUの概略  実行時間の計測  整数加算、減算の実装  整数乗算の実装  Haswell向けの改良  その他のトピック / 282
  • 3. BN曲線  𝐹𝑝上で定義される埋め込み次数12の楕円曲線  𝐸: 𝑦2 = 𝑥3 + 𝑏, 𝑏 ∈ 𝐹𝑝  𝑝 ≔ 𝑝 𝑧 = 36𝑧4 + 36𝑧3 + 24𝑧2 + 6𝑧 + 1 𝑧が64bitなら𝑝は256bitぐらいの素数  𝑟 ≔ 𝑟 𝑧 = 36𝑧4 + 36𝑧3 + 18𝑧2 + 6𝑧 + 1  𝑡 ≔ 𝑡 𝑧 = 6𝑧2 + 1  #𝐸(𝐹𝑝) = 𝑟 / 283
  • 4. 記号  𝜋: 𝑥, 𝑦 → 𝑥 𝑝 , 𝑦 𝑝  Frobenius写像  BN曲線に対してはtrace(𝜋 𝑝) = 𝑡  𝑓𝑠,𝑄: 𝐸上の有理関数(𝑠は整数𝑄は𝐸上の点)  div 𝑓𝑠,𝑄 = 𝑠 𝑄 − 𝑠 𝑄 − 𝑠 − 1 𝒪 を満たすもの 𝑠 𝑄 は 𝑄 の形式的な𝑠倍、 𝑠 𝑄は𝑄の 𝑠 倍された点を意味する  𝑙 𝑄1,𝑄2  𝑄1と𝑄2を通る直線 / 284
  • 5. Optimal Ateペアリング  𝐺1 = 𝐸 𝑟 ∩ ker 𝜋 𝑝 − 1 = 𝐸 𝐹𝑝 𝑟  𝐺2 = 𝐸 𝑟 ∩ ker 𝜋 𝑝 − 𝑝 ⊆ 𝐸 𝐹𝑝 12 𝑟  𝐺3 = 𝜇 𝑟 ⊂ 𝐹𝑝 12 ∗  𝑒 ∶ 𝐺2 × 𝐺1 ∋ 𝑄, 𝑃 ⟼ 𝑚 𝑄, 𝑃 𝑝12−1 𝑟 ∈ 𝐺3  𝑚 𝑄, 𝑃 ∶= 𝑓6𝑧+2,𝑄 𝑃 ∙ 𝑔 𝑄 𝑃  𝑔 𝑄(𝑃) ≔ 𝑙 6𝑧+2 𝑄,𝜋 𝑝 𝑄 𝑃 ∙ 𝑙 6𝑧+2 𝑄+𝜋 𝑝 𝑄 ,−𝜋 𝑝 2 𝑄 (𝑃) / 285
  • 6. ペアリングのアルゴリズム  1) 6𝑧 + 2 𝑄 と 𝑓6𝑧+2,𝑄 𝑃 を算出(Millerループ)  2) 𝑚 𝑄, 𝑃 = 𝑓6𝑧+2,𝑄 𝑃 ∙ 𝑔 𝑄 𝑃 を算出  3) 𝑝12−1 𝑟 乗する(最終巾) / 286
  • 7. 拡大体上の演算における戦略  𝐹 𝑝2上の乗算  x=a+bu, y = c+du, u^2 = -1  xy = (ac – bd) + ((a+b)(c+d) – ac – bd)u  従来  ac, bd, (a+b)(c+d)はFp:mulを使う  Pairing2010における主要アイデア  Fp:mul = mul256 + mod512 mul256 : 256ビット整数乗算mul256  64bit乗算命令は速い(3clk, latency, 1clk throughput) mod512 : Montgomeryリダクション  mul256の結果に対する加減算 ac, bd, (a+b)(c+d)を512bit整数のまま加減算 mod512の回数が3回から2回になる  512bit加減算は増える / 287
  • 8. Aranhaらによる改良  𝐹 𝑝6などの拡大体にも容易に適用可能  拡大体の係数もより小さいものに  𝑏 = 2, z = −(262 + 255 + 1)  𝐹 𝑝2 = 𝐹𝑝 U / U2 − 𝛽 , 𝛽 = −1 ∈ 𝐹𝑝  𝐹 𝑝6 = 𝐹 𝑝2 V / V3 − 𝜉 , 𝜉 = 1 + U ∈ 𝐹 𝑝2  𝐹 𝑝12 = 𝐹 𝑝6 W / W2 − V , 𝛾 = 𝑉 ∈ 𝐹 𝑝6  実装  最新の実装は上記を踏襲し,細部を改良  https://github.com/herumi/ate-pairing/ 0.35msec@Haswell(i7-4700MQ 3.4GHz) / 288
  • 9. x64 CPU概略  15個の汎用64bitレジスタ  rax, rbx, rcx, rdx, rsi, rdi, rbp, r8, r9, ..., r15  フラグレジスタ  演算結果に応じて変わる1bitの情報群 CF : 加算時に結果が64bitを超えた、減算でマイナスになった ZF : 結果が0になった SF : 結果の最上位ビットが1だった  呼び出し規約  関数の引数に対応するレジスタ名 WindowsとLinuxで異なる  Windows : rcx, rdx, r8, r9  Linux : rdi, rsi, rdx, rcx  関数の中で壊してよいものと元に戻す必要のあるもの Linux : r12, ..., r15, rbx, rbp, Win : 加えてrsi, rdi / 289
  • 10. 算術演算  加減算  add x, y // x ← x + y;  sub x, y // x ← x – y;  carryつき加減算  adc x, y // x ← x + y + CF; 繰り上がりを加味  sbb x, y // x ← x – y – CF; 繰り下がりを加味  乗算  64bit x 64bit → 128bit  mul x // [rdx:rax] ← x * rax (rax, rdxレジスタ固定)  除算  128bit / 64bit = 64bit あまり 64bit  div x // [rdx:rax] / x ; 商 : rax, あまり : rdx / 2810
  • 11. 条件比較  演算結果に応じてフラグが変わる  フラグに応じて条件分岐する  こういうコードはこんな感じ  jg (jmp if greater), jge(jmp if greater or equal)などなど / 2811 if (x >= y) { Aの作業 } else { Bの作業 } cmp x, y // x-yの計算結果をCFに反映(CF = x >= y ? 0 : 1) jnc LABEL_A // jmp to LABEL_A if no carry Bの作業 jmp NEXT LABEL_A: Aの作業 NEXT:
  • 12. アセンブラの種類  gas, NASM, MASMなど  静的なアセンブラ  マクロや条件式などの文法はそれぞれ独自構文  inline assembler  おもにgcc(64bit Visual Studioでは非サポート)  コンパイラが多少最適化してくれることも  記述が難しい  LLVM  抽象度の高いアセンブラ/JIT可能  carryの扱いが難しく今回の用途では性能を出しにくい  Xbyak(拙作)  抽象度は低い(gasやNASMと同じ)/JIT可能  C++の文法でアセンブラをかける / 2812
  • 13. 実行時間の測り方  Vtune(Intel), CodeAnalyst(AMD)など  CodeAnalystは無料 Intel CPUでも使える  perfコマンド(Linux only)  perf listで測定したいパラメータを表示 instructions branch-missessなどCPUによって様々なものがある  perf stat –e L1-icache-load-misses 実行コマンド / 2813
  • 14. rdtsc  CPUがもつカウンタ  (2.8GHzなら1/2.8 nsec単位で)一つずつ増える  Turboboostは切った方が周波数が固定になってよい 駄目なら重たい処理を先に実行させてトップスピードにさせる  マルチプロセス向けにrdtscpというのもある  Xbyakではrdtscの薄いラッパークラスClockを提供  clk.begin(), clk.end()で測定したい関数をはさむ  最後にclk.getClock() / clk.getCount()で平均値を取得 / 2814 Xbyak::util::Clock clk; for (int i = 0;i < N; i++) { clk.begin(); some_function(); clk.end(); } printf("%.2fclk¥n", clk.getClock() / double(clk.getCount()));
  • 15. 256bit加算  記法  xi, yi, ziなどは64bitレジスタを表す  [x3:x2:x1:x0]で256bit整数を表す(x0が最下位の64bit)  256bit整数z[]に256bit整数x[]を足すコードは次の通り  注意  z[], x[]が256bitフルに入ってると結果が257bitになる  今回はpを254bitに選んだため0 <= x, z < pならあふれない 他にも様々な箇所で桁あふれがおきないため処理の簡略化が可能 そのためセキュリティレベルが128bitではなく127bit / 2815 // [z3:z2:z1:z0] += [x3:x2:x1:x0] add z0, x0 adc z1, x1 // carryつき adc z2, x2 // carryつき adc z3, x3 // carryつき
  • 16. 256bit加算を関数にする  呼び出し規約にしたがってレジスタを使う  なかなか面倒  XbyakのStackFrameを使うとある程度抽象化、自動化可能 LLVMはより汎用的にできる / 2816 //addNC(uint64_t z[4],const uint64_t x[4],const uint64_t y[4]); void gen_AddNC() { Xbyak::util::StackFrame sf(this, 3); //引数3個の関数 const Xbyak::Reg64& z = sf.p[0]; // 一つ目の引数 const Xbyak::Reg64& x = sf.p[1]; // 二つ目の引数 const Xbyak::Reg64& y = sf.p[2]; // 三つ目の引数 mov(rax, ptr [x]); add(rax, ptr [y]); mov(ptr [z], rax); for (int i = 1; i < 3; i++) { mov(rax, ptr [x + i * 8]); adc(rax, ptr [y + i * 8]); mov(ptr [z + i * 8], rax); } }
  • 17. gen_addNCの結果  WindowsとLinuxのそれぞれに応じたコード生成  StackFrameはスタックを確保したり一時変数を使ったり、 rcx, rdxを特別扱いする指定もできる 自動的にレジスタの退避復元をおこなう / 2817 // Windows(引数はrcx,rdx,r8の順) mov rax,ptr [rdx] add rax,ptr [r8] mov ptr [rcx],rax mov rax,ptr [rdx+8] adc rax,ptr [r8+8] mov ptr [rcx+8],rax mov rax,ptr [rdx+10h] adc rax,ptr [r8+10h] mov ptr [rcx+10h],rax ret // Linux(引数はrdi,rsi,rdxの順) mov rax,ptr [rsi] add rax,ptr [rdx] mov ptr [rdi],rax mov rax,ptr [rsi+0x8] adc rax,ptr [rdx+0x8] mov ptr [rdi+0x8],rax mov rax,ptr [rsi+0x10] adc rax,ptr [rdx+0x10] mov ptr [rdi+0x10],rax ret
  • 18. Fp::addの実装  addNCした結果zがz>=pならばpを引く  if (z >= p) z -= p;  アセンブラレベルでの比較の方法  z=[z3:z2:z1:z0]とx=[x3:x2:x1:x0]はどちらが大きいか  1. 頭から比較する  分岐がきわめて多くなる 連続する分岐命令は好まれない  2. 引いてから考える  分岐は1回 / 2818 cmp z3, x3 ja z_gt_x // z3 > x3 jb otherwise // z3 < x3 cmp z2, x2 // here z3 == x3 ja z_gt_x // z2 > x2 jb otherwise // z2 < x2 ... z_gt_x: ... otherwise:tmp_z = z // zの値を退避(mov x 4) subNC z, p // 引いてみる(z -= p) jnc .next // z >= 0ならnextへ z = tmp_z // zの値を復元(mov x 4) .next:
  • 19. 分岐しないFp::addの実装  CPUは分岐予測をする  当たると大体1clk  外れると大体20clk  一般のデータでは偏りがあるので結構精度よく当たる  が、今回はランダムなので的中率は50%→平均10clk  分岐予測を排除する  条件移動命令cmovXX 2clk latency 1clk thrgouthput  addの二つの実装 分岐あり1.39Mclk, 分岐なし1.35Mclk もちろんCPUによって異なる可能性あり(sandy, ivyで効果あり) 単純ベンチだと分岐予測があたって分岐あり版が速くみえるかも / 2819 mov ti, zi x 4 subNC z, p cmovc zi, ti ; 引きすぎてたら戻す
  • 20. Fp::subの実装  subNCした結果が負ならpを足す  addと違ってsubNCした時のCFを見ればよいので比較不要  分岐を使った実装  cmovを使った実装  0クリア  cmov + メモリロード  加算 結構命令数が多いので分岐に対してそれほどメリットがない  cmovを使わない実装  命令数は同じだが cmovよりは速い@sandy / 2820 // z -= xの直後 jnc .next z[] += p[] .next: t[] = 0 cmovc t[] p[] //t[] = CF ? p[0] : 0 z[] += t[] sbb t, t // t = CF ? -1 : 0 and t[], p[] // t = CF ? p : 0 z[] += t[]
  • 21. 256ビット加減算の命令順序  メモリから読んで演算する二つの方式  方式A(メモリまとめ読み) 方式B(メモリと演算を交互に)  実験によるとどちらが速いかCPUにより異なる Opteron, i7は方式Aが速い Westmereは方式Bが速かった  out of orderだから関係ないと思ったが1%弱違った  実行時のCPU判別によりいずれかを選択 上記方式はコード全般にわたって適用される / 2821 z0 ← x[0] z1 ← x[1] z2 ← x[2] z3 ← x[3] z0 ← z0 + y[0] z1 ← z1 + y[1] with carry z2 ← z2 + y[2] with carry z3 ← z3 + y[3] with carry z0 ← x[0] z0 ← z0 + y[0] z1 ← x[1] z1 ← z1 + y[1] with carry z2 ← x[2] z2 ← z2 + y[2] with carry z3 ← x[3] z3 ← z3 + y[3] with carry
  • 22. 256ビットx256ビット乗算(1/2)  256ビット整数を64ビット整数4個の組で表現する  64ビット→320ビット乗算4回と320ビット加算3回  筆算方式でmulするごとにaddを行う 繰り上がり加算が3回余計に増える / 2822 𝑥3 𝑥2 𝑥1 𝑥0 𝑦 𝑥0 𝑦 𝑥1 𝑦 + +(繰り上がり) 𝑥2 𝑦 + +(繰り上がり) ・・・ 1. 𝑥0 𝑦を計算 2. 𝑥1 𝑦を計算 3. 𝑥0 𝑦 𝐿 + 𝑥1 𝑦 𝐻 t0 = 𝑥1 𝑦 𝐻 + 𝑐𝑎𝑟𝑟𝑦 4. 𝑥2 𝑦を計算 5. 𝑥2 𝑦 𝐿 + 𝑡0 𝑡1 = 𝑥2 𝑦 𝐻 + 𝑐𝑎𝑟𝑟𝑦 6. ...
  • 23. 256ビットx256ビット乗算(2/2)  乗算4回してから加算すると余計な加算が不要  ただし乗算結果を保持するワークエリアが必要  mulがCFを変更するためadcと同時に使えない  15個のレジスタを使い回して一時メモリを使わずに実装 / 2823 1. [𝑥𝑖 𝑦](𝑖 = 0 … 3)を計算 2. それらをまとめて加算 ↓ 加算は4回 𝑥3 𝑥2 𝑥1 𝑥0 𝑦 𝑥0 𝑦 𝑥1 𝑦 𝑥2 𝑦 𝑥3 𝑦 加算が終わるまでどこかに 保持する必要がある
  • 24. 256ビットx256ビット乗算 for Haswell  HaswellではCFを変更しないmulxが導入された  加算(add, adc)しつつ乗算を繰り返しおこなえる  必要なレジスタ数が減る  退避、復元のためのmov命令が減る  Montgomery reductionにも適用可能  ペアリング全体で13%の高速化  1.33Mclkから1.17Mclkへ(@Core i7 4700MQ 2.4GHz) / 2824 mov(a, ptr [py]); | ↓ mul(x); | mul(x); mov(t0, a); | mov(t3, a); mov(t1, d); | mov(a, x); mov(a, ptr [py + 8]); | mov(x, d); mul(x); | mul(qword [py + 24]); mov(t, a); | add(t1, t); mov(t2, d); | adc(t2, t3); mov(a, ptr [py + 16]);| adc(x, a); ↓ | adc(d, 0); mov(d, x); mulx(t1, t0, ptr [py]); mulx(t2, a, ptr [py + 8]); add(t1, a); mulx(x, a, ptr [py + 16]); adc(t2, a); mulx(d, a, ptr [py + 24]); adc(x, a); adc(d, 0);
  • 25. 記述の簡便さのための手法  各種2項演算はsrc x 2 + dstのglobal関数を作る  Fp::add(z, x, y); // z = x + yなど  &z == &x == &yなどのときでも正しく動くように注意  演算子オーバーロード  Fp operator+(const Fp&, const Fp&)などをFp::addを使 って定義する z = x + y;などとかける。  Fp2, Fp6, Fp12などの拡大体でも同様に作る  コピペばかりになって間違いやすい / 2825
  • 26. CRTPによる半自動的生成手法  add, subなどを使ってoperator+, operator-を定義 するtemplateクラス  Fp, Fp2などはadd, subさえつくればaddsubmulを 継承することでoperator+が使えるようになる  virtual継承ではないので呼び出し時のコストは(通常)ない / 2826 template<class T, class E = Empty<T> > struct addsubmul : E { template<class N> T& operator+=(const N& rhs) { T::add(static_cast<T&>(*this), static_cast<T&>(*this), rhs); return static_cast<T&>(*this); } ... strut Fp : addsubmul<Fp>{ static void add(Fp&, const Fp&, const Fp&); };
  • 27. 記法の簡便さと演算性能  z = x + y;とFp::add(z, x, y);  一般的に前者の方が書きやすく可読性も高い  しかし隠れた一時変数の生成とコピーに注意する  x + yの結果をtmpに保存 してz = tmpを実行  方針  最初は数式を書きやすい 前者で始める  動くことがわかったら 一時変数や移動を減らす ように後者に置き換える 式Templateによる一時変数 除去テクニックはあるが 正直使いにくい、挙動を 把握しにくいため勧めない / 2827 // Fp::add(z, x, y); lea r8,[y] lea rdx,[x] lea rcx,[z] call [mie::Fp::add] // z = x + y; lea r8,[rbp+7] lea rdx,[rbp-19h] lea rcx,[rbp-39h] call [mie::Fp::add] movaps xmm0,[rbp-39h] //データ移動 movaps [rbp+37h],xmm0 movaps xmm1,[rbp-29h] movaps [rbp+47h],xmm1
  • 28.  Fp6などの演算は基礎体のmulやaddを呼び出す  mulはレジスタをフルに使うため関数の中でレジスタの退避 と復元をおこなっている  連続してmulを呼び出すならその間の復元と退避は除去可能  退避復元をしない専用関数を用意する 呼び出し規約からの逸脱  コンパイラの関知しないところのため手作業が必要 LLVMがこの分野で使えるならoptに任せることも可能になるか  メリット  速度向上  デメリット  デバッグが難しい かもしれない Fp2_mul: call Fp_mul call Fp_mul ret Fp_mul: レジスタの退避 本体 レジスタの復元 レジスタの退避・復元の省略の一般論 / 2828 Fp2_mul: call in_Fp_mul call in_Fp_mul ret // Cからは呼べない in_Fp_mul: 本体