從非硬化子節點派生父私鑰
引自BIP 32:
一個可能不會立即明顯的弱點是,知道父擴展公鑰加上任何從它傳下來的非硬化私鑰等價於知道父擴展私鑰(因此每個私鑰和公鑰都從它傳下來)。
這是怎麼做到的?
首先,我們必須了解 BIP 32 如何派生非硬化私鑰和公鑰。
從 BIP 32 開始,從擴展父私鑰派生子私鑰:
讓 I = HMAC-SHA512(Key = c par , Data = ser P (point(k par ))) || ser32(i))。
將 I 拆分為兩個 32 字節序列,即 I L和 I R。
返回的子密鑰 K i是 parse 256 (I L ) + k par (mod n)。
因此,私鑰是父私鑰加上 HMAC-SHA512 函式的前 256 位,其中密鑰是父私鑰的鏈碼,散列數據是對應於擴展的公鑰序列化的串聯私鑰和子鍵索引。這裡要注意的重要一點是,HMAC-SHA512 雜湊是公鑰的雜湊,而不是私鑰的雜湊。
從 BIP 32,從擴展的父公鑰派生子公鑰:
讓 I = HMAC-SHA512(Key = c par , Data = ser P (K par ) || ser32(i))。
將 I 拆分為兩個 32 字節序列,即 I L和 I R。
返回的子鍵 K i是 point(parse 256 (I L )) + K par。
子公鑰是父公鑰加上從 HMAC-SHA512 函式的前 256 位生成的公鑰,其中密鑰是父密鑰的鏈碼,數據是父公鑰與索引的串聯子公鑰。
請注意,在派生子私鑰和子公鑰時,您實際上是如何散列相同的東西的?您正在使用相同的密鑰(父密鑰的鏈碼)和相同的數據(父公鑰的串聯和子密鑰的索引)執行 HMAC-SHA512 函式。該散列的前 256 位成為某種私鑰,並將該私鑰添加到主私鑰中以成為實際的子私鑰。它的公鑰計算並與父公鑰相加成為子公鑰。
因此,要獲得主私鑰,我們需要做的就是獲取我們現在擁有的子私鑰,並從中減去由 HMAC-SHA512 函式生成的私鑰。為此,我們需要三樣東西,鏈碼、父公鑰和子密鑰索引。
鏈碼和父公鑰來自擴展父公鑰 (
xpub
),因為它對鏈碼和公鑰都進行了編碼。子密鑰索引可以通過從父公鑰派生子公鑰來輕鬆找到,直到我們得到與我們擁有的子私鑰對應的公鑰並保存密鑰索引。
有了這三樣東西,我們就可以執行 HMAC-SHA512 函式,得到 512 位散列。現在我們可以獲取子私鑰並從中減去我們剛剛生成的雜湊的前 256 位整數。我們的結果是父私鑰。將它與我們從擴展父公鑰中檢索到的鏈碼結合起來,我們就擁有了擴展父私鑰。
此技術僅適用於非硬化派生。強化派生可以防止這種情況發生,因為它通過散列父私鑰來生成子私鑰。但是,這也意味著您不能從父公鑰生成子公鑰。