Security
如何從共享相同 k 值的兩個簽名中導出私鑰?
我編寫自己的 ECDSA 簽名算法只是為了創建單元測試。
有了它,我創建了兩個簽名,這些簽名進入了事務56ec7ca7df…,從1GXFXm3es…發送。這些簽名使用相同的 k 值,但決不能重複使用 k 值。
後來,有人能夠從 1GXFXm3es 竊取 0.0016 btc….並將它們發送到 17WRjamox6VhTUaHsTWfFnMNDYHvwCtWio。
因此,必須有人監視區塊鍊是否存在此類錯誤,並在遇到此類錯誤時竊取資金。
如何從共享相同 k 值的兩個簽名中導出私鑰?
ECDSA 簽名是對 (r,s),其中 r=(k G).x mod n,並且 s = (m + r x)/k mod n,其中 x 是密鑰,k 是隨機數,m是消息。
如果您有兩個 s 值 s1 和 s2 用於相同的密鑰並且具有相同的隨機數 k(因此具有相同的值 r),則以下成立:
- s1 = (m1 + r*x)/k
- s2 = (m2 + r*x)/k
由此我們可以得出:
- s1 * k = m1 + r*x
- s2 * k = m2 + r*x
- (s1 - s2) * k = m1 - m2
- k = (m1 - m2) / (s1 - s2)
- x = (s1 * (m1 - m2) / (s1 - s2) - m1) / r
- x = (m1 s2 - m2 s1) / (r*(s1 - s2)) (所有 mod n)
因此,您不僅可以輕鬆檢測具有相同隨機數的簽名(它們具有可辨識的 r 值),而且一旦有人看到兩個簽名,就有一個簡單的公式可以計算私鑰。
至少從 2013 年開始,這種攻擊就已經在比特幣網路上廣為人知並被積極利用:https ://bitcointalk.org/index.php?topic=271486.0 。不要重複使用 k 值。使用 RFC6979 確定性但安全地生成它們。
另請注意,隨機數不同是不夠的。它們也不能以已知的方式關聯。例如,您不能將 k 用於一個簽名,而將 k+1 用於下一個工作。