楕円曲線暗号のための数学5(NAF)
初めに
前回、楕円曲線のスカラー倍算の高速化手法の一つ、ウィンドウ法を紹介しました。
今回は、それを改善してテーブル作成コストを半減するNAFという手法を紹介します。
符号つき2進数
楕円曲線の点の減算
たとえば 0b10111
なので
しかし、
これは、通常の2進数が0と1だけで表現するのに対して、0, 1, -1で表現していることになります。この様な表現を符号つき2進数と呼んで、
NAF
符号つき2進数は冗長で、単なる1でも
元々の目的は、楕円曲線の点のスカラー倍算を効率よく計算したいというものですから、普通の2進数で計算するよりもコストがかかっては意味がありません。
1(あるいは-1)の立ってるビットが一番小さくなる形が望ましいです。そのような性質をハミング重みが最小といい、そのように表現された符号つき2進数の中でも、0でないビット(
たとえば
23の場合は
アルゴリズム的には普通の2進数展開した後、下位ビットから1が連続しているところがあれば
通常2進数からNAFへの変換の例
ビット | 5 | 4 | 3 | 2 | 1 | 0 |
---|---|---|---|---|---|---|
2進数 | 0 | 1 | 1 | 1 | 1 | 1 |
NAF | 1 | 0 | 0 | 0 | 0 | -1 |
NAFにすると元の2進数のビット長よりも1ビット長くなる場合があることに気をつけてください。
ウィンドウ法とNAFの組み合わせ
ウィンドウ法は
ここで
このような数値に分解するには普通の2進数を下位ビットからみて、偶数(0)である限りスキップし、1が始まったらそこから
Pythonで記述すると次のようになります。
def naf(x, w):
tbl = []
H = 1<<(w-1)
W = H*2
mask = W-1
zeroNum = 0
while x > 0:
while x & 1 == 0:
x >>= 1
zeroNum += 1
for i in range(zeroNum):
tbl.append(0)
v = x & mask
x >>= w
if v & H:
x += 1
v -= W
tbl.append(v)
zeroNum = w-1
return tbl
w=4 のときの具体例
また、係数
4ビットNAF的分解
x | 2進数 | 4ビットNAF的分解 |
---|---|---|
0 | 0 | 0 |
1 | 1 | 1 |
2 | 10 | 1 0 |
3 | 11 | 3 |
4 | 100 | 1 0 0 |
5 | 101 | 5 |
6 | 110 | 3 0 |
7 | 111 | 7 |
8 | 1000 | 1 0 0 0 |
9 | 1001 | 1 0 0 0 -7 |
10 | 1010 | 5 0 |
11 | 1011 | 1 0 0 0 -5 |
12 | 1100 | 3 0 0 |
13 | 1101 | 1 0 0 0 -3 |
14 | 1110 | 7 0 |
15 | 1111 | 1 0 0 0 -1 |
16 | 10000 | 1 0 0 0 0 |
17 | 10001 | 1 0 0 0 1 |
18 | 10010 | 1 0 0 0 -7 0 |
19 | 10011 | 1 0 0 0 3 |
20 | 10100 | 5 0 0 |
21 | 10101 | 1 0 0 0 5 |
22 | 10110 | 1 0 0 0 -5 0 |
23 | 10111 | 1 0 0 0 7 |
24 | 11000 | 3 0 0 0 |
25 | 11001 | 1 0 0 0 0 -7 |
26 | 11010 | 1 0 0 0 -3 0 |
27 | 11011 | 1 0 0 0 0 -5 |
28 | 11100 | 7 0 0 |
29 | 11101 | 1 0 0 0 0 -3 |
30 | 11110 | 1 0 0 0 -1 0 |
31 | 11111 | 1 0 0 0 0 -1 |
コスト計算
前回の修正ウィンドウ法の67よりもかなり小さくなりました。
Discussion