跟大家一起學習區塊鏈技術系列之一 比特幣之錢包(4)HD

層級確定性密鑰生成(Hierarchical Deterministic)

Hierarchical Deterministic 簡稱HD

HD密鑰生成和傳輸協議(HD協議)大大簡化錢包的備份,消除了不同基於同一個錢包的程序之間重複通信的需要,允許各自獨立的創建子賬戶,給每一個父賬戶監視和控制子賬戶的能力,即便子賬戶被洩露。把每個賬戶分成全訪問和限制訪問部分,這樣非信任用戶或程序只能允許接受或監視支付,但不能花掉他們。

HD協議利用ECDSA公鑰創建函數,point(),這個函數輸入私鑰(一個大的整數),輸出圖上的點(公鑰):

point(private_key) == public_key

因為point()的工作方式,通過一個存在的公鑰(父)和從一個數值(i)得到公鑰的組合,創建一個子公鑰是可能的。這個子公鑰也是通過point()計算出來的,輸入是對原始的私鑰(父私鑰)加i,然後對一個所有比特幣軟件的全局的常量p取餘數:

point( (parent_private_key + i) % p ) == parent_public_key + point(i)

這意味著兩個或多個獨立的程序在順序一致的情況下,並且不需要更多的通信,從一個單獨的密鑰對可以創建一系列的子密鑰對。更進一步來說,分發新的密鑰的程序不需要接觸私鑰就可以了,使得公鑰分發程序可以運行在一個可能不安全的平臺上,比如公共web服務。

子公鑰也可以創建他們自己的子公鑰(孫公鑰),重複子密鑰的創建過程:

point( (child_private_key + i) % p ) == child_public_key + point(i)

不管是創建子公鑰還是進一步繼承公鑰,一個可預測的整數值序列不比所有的交易用一個地址好多少,一個人知道了一個子公鑰就可以找到從同一個父公鑰創建出來的其他所有的子公鑰。我們用隨機種子來代替產生一個確定的數值序列,這樣如果沒有種子的話子公鑰之間的聯繫就不可見了。

HD協議使用一個單獨的根種子來創建兒子、孫子的層級,並且通過沒有聯繫的確定產生的整數數值產生其他繼承的密鑰。每個子密鑰也從父母那得到了一個確定產生的種子,稱為鏈碼,洩露一個鏈碼不會洩露整個層級的序列,這允許主鏈碼可以繼續使用,即使比如一個基於web的公鑰分發程序被黑。

跟大家一起學習區塊鏈技術系列之一 比特幣之錢包(4)HD

如上面描述,HD密鑰產生需要四個輸入:

  • 父私鑰和父公鑰,都是未壓縮的256bit ECDSA密鑰。

  • 父鏈碼,看起來是隨機數的256bit的數

  • 索引號,程序定義的32bit整數。

如上面插圖,在正常形式裡,父鏈碼,父公鑰和索引號輸入到哈希函數(HMAC-SHA512),輸出一個512bit確定的但是看起來隨機的數據。右半部256bit用作新的鏈碼,左半部256bit用作和父私鑰或父公鑰組合的整數,相應的產生子私鑰和子公鑰:

child_private_key == (parent_private_key + lefthand_hash_output) % G
child_public_key == point( (parent_private_key + lefthand_hash_output) % G )
child_public_key == point(child_private_key) == parent_public_key + point(lefthand_hash_output)

指定不同的索引號將會從相同的父密鑰生成互不相關的子密鑰。用子密鑰重複這個步驟將會創建互不相關的孫密鑰。

因為創建子密鑰需要一個密鑰和一個鏈碼,密鑰和鏈碼一起被稱為擴展密鑰。一個擴展的私鑰和相應的擴展公鑰有相同的鏈碼。主私鑰(最頂層)和主鏈碼是從隨機數得來的,如下圖。

跟大家一起學習區塊鏈技術系列之一 比特幣之錢包(4)HD

一個根種子是從128bit,256bit或512bit的隨機數計算來的。這個根種子最小128bit是用戶需要備份的唯一的數據,為了得到每一個密鑰,需要由一個特別的錢包程序用特別設置創建的。

警告:截止到目前,HD錢包並不期待是全兼容的,所以用戶必須對一個特別的種子使用一樣的HD錢包程序,並且是相同HD有關的設置。

根種子被計算哈希得到512bit看起來隨機的數據,從這個數據計算出主私鑰和主鏈碼。主公鑰從主私鑰通過point()得到,和主鏈碼一起稱為擴展公鑰。主擴展密鑰和其他擴展密鑰功能是一樣的;僅僅因為他們在層級的最頂部看起來特別而已。


分享到:


相關文章: