1. 程式人生 > >數字貨幣開發專題(51%攻擊技術和執行方法)

數字貨幣開發專題(51%攻擊技術和執行方法)

區塊鏈愛好者(QQ:53016353)

數字貨幣51%攻擊的成功概率

Satoshi的論文的描述了指定算力的攻擊成功的概率計算方式 本文試圖通過已有的block計算實際數字貨幣51%攻擊的概率和需要的時間 通過分析目前已經生成的block時間和密度分佈計算實際數字貨幣51%攻擊的概率和需要的時間


Satoshi計算的基於泊松分佈的理論概率
看過論文的可以直接跳過這一節,看實際概率的估算




下面截圖來自中文版本: 理論概率


如果p>q,則攻擊者掌握了一半以上的算力,那麼概率上永遠是贏的。該事件(攻擊者勝出)的概率是固定,且N次事件之間是相互獨立的,那麼這一系列隨機過程符合泊松分佈(Poisson Distribution)。Z個塊時,攻擊者勝出的期望為lambda:


攻擊者在攻擊時已經偷偷的計算了k個塊,那麼這k個塊概率符合泊松分佈(下圖左側部分),若k<=z,那麼追趕上後續z-k個塊的概率為(q/p)z-k,即: 展開為如下形式:


c lang 版本:


#include double AttackerSuccessProbability(double q, int z){    double sum    = 1.0;    double p      = 1.0 - q;    double lambda = z * (q / p);    int i, k;    for (k = 0; k <= z; k++) {        double poisson = exp(-lambda);        for (i = 1; i <= k; i++)            poisson *= lambda / i;        sum -= poisson * (1 - pow(q / p, z - k));    }    return sum;}
python 版本:


def  attackerSuccessProbability(q, z):   sum =1.0   p = 1.0 - q    lamba = z * (q/p)   i = 0;   k = 0;   for k in range(z +1):      poisson = exp(-lamba)      for i in range(1,k+1):          poisson *=(lamba/i)      sum -=poisson * (1 - pow(q/p, z-k))         return sum
對其進行運算,我們可以得到如下的概率結果,發現概率對z值呈指數下降。


當q=0.1時


z=0 P=1.0000000z=1 P=0.2045873z=2 P=0.0509779z=3 P=0.0131722z=4 P=0.0034552z=5 P=0.0009137z=6 P=0.0002428z=7 P=0.0000647z=8 P=0.0000173z=9 P=0.0000046z=10 P=0.0000012
當q=0.3時


z=0 P=1.0000000z=5 P=0.1773523z=10 P=0.0416605z=15 P=0.0101008z=20 P=0.0024804z=25 P=0.0006132z=30 P=0.0001522z=35 P=0.0000379z=40 P=0.0000095z=45 P=0.0000024z=50 P=0.0000006
求解令P<0.1%的z值:


q=0.10 z=5q=0.15 z=8q=0.20 z=11q=0.25 z=15q=0.30 z=24q=0.35 z=41q=0.40 z=89q=0.45 z=340
當q = 0.51時,成功概率已經大於1:


z=0 P=1.000000z=1 P=1.014415z=2 P=1.020987z=3 P=1.025839z=4 P=1.029825z=5 P=1.033268z=6 P=1.036329z=7 P=1.039102z=8 P=1.041648z=9 P=1.044010
**注意: 以上是假定符合泊松分佈,來計算的,但實際上由於目前算力被各大礦池壟斷,二項分佈更準確一些


asdfaoeu計算的基於二項分佈的概率


時間分佈曲線


數字貨幣51%攻擊成功需要的理論時間估算
Satoshi論文中只說了攻擊成功的概率,沒有計算攻擊成功需要的時間


以下以固定算力估計算數字貨幣51%攻擊成功需要的時間


rateA :A 誠實節點 49% 算力


rateB :B 攻擊節點 51% 算力


A B都在各自的blockchain分支上計算


計算 B偷挖n個塊後需要多長時間超過A?


A 和 B 概率固定的時候


固定概率計算, B偷挖n個block後經過一段時間後超過A,這是A挖了m個block


rateA = 100 *10/49 #A 計算一個塊需要的分鐘數


rateB = 100 *10/51 #B 計算一個塊需要的分鐘數


m *rateA = (m + n) * rateB #超過1個塊才能有效攻擊


m (rateA - rateB) = n rateB


m = n * rateB /(rateA - rateB)


需要的時間為 t = m * 10(分鐘)


計算結果為結果吧:


   z=1  t=190 (分鐘)   z=2  t=380   z=3  t=570   z=4  t=760   z=5  t=950   z=6  t=1140   z=7  t=1330   z=8  t=1520   z=9  t=1710   z=10 t= 1900
大概2小時內,6個block內, 51%的算力,追上的概率為40%左右


當然這個很不準確,因為實際時間會根據A,B生成block的需要時間的概率密度上下浮動


基於已有的block時間計算的概率
Satoshi的論文給出了數字貨幣51%攻擊的理論概率,但是實際上的攻擊成功概率要受很多因素影響,包括但不限於:


算力變化: 算力一直增長,總體趨勢一直向上,所以生成block的實際時間其實小於10分鐘,在9分鐘左右
難度變化: 難度每隔2016block,大約2周調整一次,實際上由於算力增長,一直小於2周
time變化: timestamp,在不同miner之間並不一致,所以有同步導致的影響
挖礦演算法: 如果nonce正好落在開始計算的數字附近, 運氣, 比如礦池總是從0開始計算nonce,nonce恰好落在0附近,如果相反則需要更多的時間
實際概率計算
如何計算實際的51%的攻擊概率呢?


bitcoin建立到現在總計產生30多萬個block, 我們可以用這30多萬個block的時間來估算數字貨幣51%攻擊實際的概率和需要的時間


以下以6個confirm為例,來計算實際可能的概率


正常的 blockchain, 我們稱之為C


[]----->[]----->[]----->[]----->[]----->[]----->[] C blockchain
誠實節點計算的 A blockchain


攻擊節點計算的 B blockchain


[]----->[]----->[]----->[]----->[]----->[]----->[] A blockchain        \         []----->[]----->[]----->[]----->[]----->[]----->[] B  blockchain
分別計算每連續6個block的生成時間間隔:


t1 = blk5.time - blk0.time t2 = blk6.time - blk1.time ..... tx = blkn.time - blk(n-5).time


這樣得到100%算力的C的連續生成6個塊的時間集合 {t1,t2,t3....tx} TC1


然後用同樣的方法計算連續生成7個block的時間間隔, 得到100%算力的C的連續生成7個塊的時間集合 {t1,t2,t3....} TC2


對TC1繪圖,得到正常的C blockchain 連續生成6個block時間分佈曲線


x為連續的6個block


y為生成連續的6個block的時間


時間分佈曲線


對時間排下序得到下圖,可以得到連續生成6個block需要的最少時間和最多時間


時間分佈曲線


然後對T1計算,每間隔10秒內Tx的數目, 得到{len(T1...Tx),len(Tx+1....Tx+n)....},得到密度分佈曲線,如下


時間分佈曲線


上圖可以看出連續生成6個block需要的時間


把A和B看成一個獨立的blockchain,則 A,B生成block概率的密度分佈應該和C一致,但是由於A,B的算力下降,所以把時間軸等比縮放,


A 連續生成6個塊需要的時間集合{t1,t2,t3....} TA = TC1 * 100/(1-49)


B 連續生成7個塊需要的時間集合{t1,t2,t3....} TB = TC2 * 100/(1-51)


時間分佈曲線


得到A,B的曲線(左邊為A,右邊為B),和A可能的連續生成6個block的時間集合TA,和B連續生成7個block的時間集合TB


如果此處對是否可以縮放的疑問,可以看下面的曲線,每隔20000個block分別計算密度分佈,難度應該變化10倍左右,算力變化x倍,發現block生成時間密度曲線基本重合 時間分佈曲線


現在問題轉化為在TA中隨機選一個時間,大於TB中任意元素的概率


程式碼如下:


AB為有序集合,從小到大依次排列


AB中任意取元素a,b, 計算a>b的概率


def AB (A,B):    N = []     qz = 0.0    for i,a in enumerate(A):       n = 0       for b in B:          if a<=b: break          else: n+=1       N.append(n)    return  float(sum(N))/(len(B) *len(A))
實際的計算結果


51% 算力攻擊, height高度為280000~300000, 20000個block的生成時間密度計算成功的概率為


z=0 P=1.000000z=1 P=0.25991752883z=2 P=0.327356211643z=3 P=0.362791063488z=4 P=0.38572021231z=5 P=0.402129295953z=6 P=0.41492854999
如果覺得20000個樣本不夠,那麼以height高度為200000~300000的, 100000個的生成時間密度計算成功的概率為


z=0 P=1.000000z=1 P=0.258909623337z=2 P=0.327897207064z=3 P=0.363898341947z=4 P=0.387023480539z=5 P=0.403786580212z=6 P=0.416886094841
實際攻擊成功需要的時間
Tc2 < Tc1的時間範圍, 就是{min(Tc2) ~ max(Tc1)}為最有可能的時間為


51% 算力攻擊成時間密度計算成功的時間範圍大概為


{452s ... 13514s}
數字貨幣51%攻擊能造成什麼破壞
修改自己的交易記錄,這可以使他進行雙重支付
阻止區塊確認部分或者全部交易
阻止部分或全部礦工開採到任何有效的區塊
數字貨幣51%攻擊不能做什麼
修改其他人的交易記錄 , 因為沒有privateKey
阻止交易被髮出去(交易會被髮出,只是顯示0個確認而已)
改變每個區塊產生的比特幣數量
憑空產生比特幣
把不屬於他的比特幣傳送給自己或其他人
數字貨幣51%攻擊防範
注意長時間的大規模算力消失
有大額交易時多等幾個確認, 等待confirm超過2小時
實時檢測soft fork chain
監控從礦池發出的大額交易
監控礦池算力變化,長時間不出塊
其他注意事項
所以發起數字貨幣51%攻擊必須在短時間內完成,理由如下:


當算力小於50%時候,攻擊成功概率隨著時間變小
當算力大於50%時候,攻擊成功概率隨著時間變大
當算力大於50%的時候,隨著攻擊時間變長,從算力看攻擊成功率變大,但是失敗的概率反而變大,因為長期的大規模算力消失,必然會引起社群注意
超過2小時,則bitcoin網路不會接收新的block, 這個是btc網路規定的
思考
TODO 什麼時候開始攻擊最合適,算力剛剛調整完畢開始攻擊? 從實際概率估算,經濟學成本到底是多少 confirm幾個塊才安全? 等多長時間才安全? 指定時間,如何計算成功概率? 指定概率,如何計算成功需要時間? * 實際的數字貨幣51%攻擊分析