L = n となる a, b に分解する tbla, tblb 2^w 個の配列を用意する tbla[0] = tblb[0] = 0 for i from 1 to 2^w-1: tbla[i] = tbla[i-1] + P # tbla[i] = i P tblb[i] = L tbla[i] # tblb[i] = i L P Q = 0 for i from 0 to ⌈L/2/w⌉: Q = 2^w Q Q = Q + tblb[bのiwビットからwビットを取り出す] Q = Q + tbla[aのiwビットからwビットを取り出す] return Q 6 / 19
( : 逆元, : 乗算) SIMDの場合 逆元はループと分岐が多いためSIMDで実装するのは煩雑で難しい SIMDによる全体のバッチ処理 +「 個の逆元をスカラーの逆元のバッチ処理」 それぞれを SIMD処理 x 0 x 1 x 7 x 8 x 9 x 15 x 8n x 8n+1 x 8n+7 各⾏ごとの積に対して スカラーに対する 逆元のバッチ処理 11 / 19
加減算・論理演算・シフト演算などは64ビット単位で 個並列のSIMDで処理する データの形 BLS12-381曲線では381ビット整数を52ビット単位に分割して64ビット整数8個で表現する 個の384ビット整数 を8個のSIMDレジスタに格納する SIMDレジスタ1個 X 00 X 01 X 02 zmm0 zmm1 zmm2 ... X 10 X 11 X 12 X 20 X 21 X 22 整数X 0 整数X 1 X 07 X 17 X 27 zmm7 12 / 19
に対して を ビットMontgomery表現と呼ぶ , 変換の高速化 通常のスカラー64ビットMontgomery表現からSIMD 52ビットMontoegomery表現への変換 : スカラー版乗算8回+SIMD版乗算1回 : 改良後 SIMD版乗算1回 x i x i R 64 x i R 52 スカラーfromMont x8 SIMD toMont x1 SIMD mont(x i , 2 32 ) x1 13 / 19