老板說,你去學一下w-NAF,哎,立馬去學~,狗腿子得自覺。
從搜索w-NAF,到NAF,到倍點運算,到ECC,再到Diffie-Hellman算法,真是人生無常,大腸包小腸。。。
ok,開始啦!!!!介紹w-NAF之前,先介紹一些預備知識吧(別看寫的不多,其實too much,看了很多雜七雜八的)~~~
1、橢圓曲線的倍點運算np double-and-add(暫且基於素曲線GFp討論:三次方程中的變量和系數都來自{0,1,2,……,p-1})
下面考慮由所有滿足橢圓曲線方程的整數對和無窮遠點O組成的集合Ep(a,b),系數a,b,變量x,y都是GFp的元素。
Ep(a,b)上的加法運算構造與定義在實數上的橢圓曲線中描述代數方式是一致的。對任何點P,Q∈Ep(a,b)
- P + O = P
- 若P= ( xp , yp),則P + ( xp , -yp) = O 。點 ( xp , -yp)是p的負元,記為-p。例如E23(1,1)上的點p(13,7),負元-p=(13,-7),-7 mod 23 =16,因此-p=(13,16),也在E23(1,1)上。
- 若P = ( xp , yp),Q = ( xq , yq),P ≠ Q,則R = P + Q =(xr ,yr)可由下列規則確定
xr =(m²-xp-xq)mod p |
yr = (m(xp - xr)- yp)mod p |
其中 P≠Q時,m=(yq - yp)/(xq - xp) mod p |
P=Q時, m= (3xp²+a)/2yp mod p |
- 乘法的定義為重讀相加。比如4p = p + p + p + p = 2p + 2p
這里主要介紹一下倍點運算算法1,2
算法1 nP倍點運算
1 Input:A positive integer n=(n[l-1] n[l] …… n[0])2,Point P 2 Output:R = nP 3 R = 0*P 4 for i = l - 1 to 0 do 5 R = 2R 6 if n[i] = 1 do 7 R = R + P 8 return R
算法2 同款np倍點運算,性能比1差,但抵抗側信道攻擊能力更強一些
1 Input:A positive integer n=(n[l-1] n[l] …… n[0])2,Point P 2 Output: R = nP 3 R = 0P 4 for i = l - 1 down to 0 do 5 R = 2R 6 R = R +n[i]R 7 return R
2、窗口方法 Windowing method :
上述倍點運算每次只掃描標量n的一個比特,窗口方法一次掃描w個比特,使點P一次完成(ni+w,……,ni+1)* P,此時點加法操作由原來的l減少到l/w。
窗口方法分為兩種:固定w位窗口(fixed window)和移動w窗口(sliding window)。
算法3 固定窗口 這里必須預先計算查找表中的值2P、3P、...,(2ω−1)P。
1 Input:A positive integer n=(n[l-1] n[l] …… n[0])2,Point P 2 Output:R = nP 3 將 n 轉化位 2^w 方式:n=(c[j-1],……,c[0])2^w 4 R = 0P 5 for k = j - 1 down to 0 do 6 R = 2^w R 7 R = R + c[k]*P 8 return R
算法4 滑動窗口 這里必須存儲奇數倍的p,3p,5p,……,{2(2ω−(-1)w)/3 - 1}P
1 Input:A positive integer n=(n[l-1] n[l] …… n[0])2,Point P 2 Output:R = nP 3 R = P 4 i = l - 1 5 while i ≥ 0 do 6 if n[i] = 0 then 7 R = 2R 8 i = i - 1 9 else 10 s = max(i - w + 1, 0) 11 while n[s] = 0 do 12 s = s + 1 13 for h =1 to i - s + 1 do 14 R = 2R 15 u = (n[i] n[i-1] …… n[s])2 16 R = R + uP 17 i = s - 1 18 return R
3、Non-adjacent form(NAF不相鄰表示形式)
NAF是一種二進制符號的表示形式,定義為n=Σli=0 di2i,其中di∈{-1,0,1},並且不能有連續相鄰的非零元素1或-1出現。因此用NAF表示數的密度約等於1/3,性能較無符號二進制表示形式要更好。將一個普通的二進制轉化為他的NAF表示形式可以使用算法5、6,如圖所示。
- 一個整數k有唯一的NAF表達形式
- 任何有符號數字表示k中NAF(K)具有最少的非零數字
- NAF(K)的長度最多比二進制K多一個比特
- 如果NAF(K)的長度是L,那么2L/3 < k < 2L+1 /3
- 在所有長度為l的NAFs中,非零位數的平均密度約為1/3。
算法5 將正整數n轉化為2-NAF形式
1 Input:A positive integer n=(n[l+1] n[l] …… n[0])2,n[l+1]=n[l]=0 2 Output:NAF (n'[l] n'[l-1] …… n'[0]) 3 4 c[0]=0 5 for i=0 to l do 6 c[i+1]=(c[i]+n[i]+n[i+1])/2 //向下取整 7 n'[i]=c[i]+n[i]-2c[i+1] 8 return NAF (n'[l] n'[l-1] …… n'[0])
算法6 將整數n轉為2-NAF形式
1 Input :A positive integer N = (n[l+1] n[l] ··· n[1] n[0])2 2 Output NAF n'=(n'[l] n'[l-1] n'[0]) 3 i ← 0 4 while N > 0 do 5 if n is odd then 6 n'[i] ← 2 − (n mod 4) 7 N ← N − n'[i] 8 else 9 n'[i] ← 0 10 N ← N/2 11 i ← i + 1 12 return NAF n'
4、應用於KP點的NAF運算
Input :A positive integer NAF(N) = (n[l] n[l] ··· n[1] n[0])2,Point P Output:Q = NP Q = 0 for i = l down to 0 do Q = 2Q if n[i] = 1 do Q = Q + P if n[i] = -1 do Q = Q - P return Q
5、A width-w NAF 結合了NAF和窗口w的特征
wNAF可以說是一種w進制表示形式,定義正整數k = Σl-1i=0 ki2i,其中,每個非零系數ki都是奇數且 |ki| < 2ω−1,kl-1≠0,任意連續的w個比特中最多只能有一個比特非零比特,w-NAF表示數的密度約等於1/(w+1)。NAF就是窗口為2的情況。
- 一個整數k有唯一的w-NAF表達形式
- NAF2(k)=NAF(k)
- NAFw(K)的長度最多比二進制K多一個比特
- 在所有長度為l,寬度為w的NAFw(K)中,非零位數的平均密度約為1/(w+1)。
算法7 將正整數k轉化為wNAF形式
1 Input :A positive integer N = (n[l] n[l] ··· n[1] n[0])2 2 Output:w-NAF(N) 3 i=0 4 while N ≥ 1 do 5 if N is odd then 6 n'[i] = N mod 2w // N mod 2w 的結果區間在[-2(w-1),2(w-1)-1] 7 N = N - n'[i] 8 else 9 n'[i] = 0 10 N = N/2 11 i = i + 1 12 return n'[i-1] n'[i-2] …… n'[0]
粘圖看個例子
6、應用於KP點的w-NAF運算
5已經把wNAF的系數k展示式算出來了,那么怎么應用捏,其實蠻簡單的。
算法8 這里必須存儲奇數倍的p,3p,5p,……,(2ω-1−1)P
1 Input :A positive integer w-NAF(N) = (n[l] n[l] ··· n[1] n[0])2,Point P 2 Output:Q = NP 3 Q = 0 4 for i = l down to 0 do 5 Q = 2Q 6 if n[i] ≠ 0 7 if n[i] > 0 do 8 Q = Q + n[i]P 9 else 10 Q = Q - n[i]P 11 12 return Q
7、curve25519中的scalar NAF稍作了解,閃退~~~~