详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

当你在myetherwallet网站中输入助记词时…疑,这啥?

加密货币钱包(Cryptocurrency Wallet)
1. 在加密货币的世界中,钱包并非储存加密货币的地方。
2. 反倒是钱包的主要功能是一个储存私钥(Private Key)的工具,私钥是一串很长的英文字母、数字组成的字串(通常是64个16进制位= 256 Bits = 32 Bytes所组成),而这条很长的字串让您有权力把自己的加密货币传送给别人。
3. 钱包可在使用者产生交易(Transaction)时使用私钥将交易签章(Digital Signature),而签章的目的除了确认使用者为货币拥有者外,还可确保在交易完成后不可否认(Non-Repudiation)此交易;而储存加密货币的地方则是负责维护区块链(Blockchain)的矿工节点内。
4. 加密货币钱包形式多样,分为离线的冷钱包(Cold Wallet)、在线的热钱包(Hot Wallet)、印在纸上的纸钱包(Paper Wallet)…等。无论何种形式的钱包,钱包的开发商均需要有一个共同遵循的规范(例如:私钥为多少位、如何依据一个随机数产生私钥等)。
比特币改进提案(Bitcoin Improvement Proposals,BIP)
1. BIP全名是Bitcoin Improvement Proposals,是开发者向比特币社群提出比特币Bitcoin新功能或改进建议的技术设计文件。
2. 根据BIP-0001改进提案,BIP总共分为:
· 描述系统面更动的标准类BIP(Standards Track BIP)
· 描述系统指导信息的信息类BIP(Informational BIP)
· 描述建议更动流程的程序类BIP(Process BIP)
分层确定性钱包(Hierarchical Determinstic Wallet,HD Wallet)
HD Wallet被BIP-0032、BIP-0039、BIP-0043、BIP-0044改进提案所共同定义,包含了钱包的设计动机、理念、实作方式等。
BIP-0032改进提案:
· BIP-0032是HD Wallet的核心提案,在系统使用SECP256K1椭圆曲线加密算法前提下,我们可用熵(Entropy)函数产生随机的32个16进制字元(128 Bits)S,
S = Entropy_128_Bits
· 将S字串透过哈希算法HMAC-SHA512产生一组64个16进制字元(256 Bits),我们将(左半边的)256 Bits字串作为父扩展私钥(Parent Extended Private Key)m;另一组(右半边的)256 Bits字串作为下一级的链码(Chain Code)c。而m可推导成父扩展公钥(Parent Extended Public Key)M。
m = Left(HMAC_SHA512(S), 256)
c = Right(HMAC_SHA512(S), 256)
M = SECP256K1(m)
· 使用子私钥求导(Child Private Key Derivation,CKDpri)函数,我们可以透过父扩展私钥来产生出index = i子私钥(Private Child Key)。
Child Private Key(Index = i) 
= m / i 
= CKDpri(m, i) 
= Left(HMAC_SHA512(c, M, i), 256)⊕ m
m / 0 = CKDpri(m, 0)
m / 1 = CKDpri(m, 1)
m / 2 = CKDpri(m, 2)

m / i = CKDpri(m, i)

详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

· 使用增强子私钥求导(Child Hardened Key Derivation,HKD)函数,我们可以透过父扩展私钥来产生出index = i’子私钥(Private Child Key)。
Child Private Key(Index = i’) 
= m / i’ 
= HKD(m, i) 
= Left(HMAC_SHA512(c, m, i), 256)⊕ m
m / 0′ = HKD(m, 0)
m / 1′ = HKD(m, 1)
m / 2′ = HKD(m, 2)

m / i’ = HKD(m, i)

详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

· 使用子公钥求导(Child Public Key Derivation,CKDpub)函数,我们可以透过父扩展公钥来产生出子公钥(Public Child Key)。
Child Public Key 
= M / i 
= CKDpub(M, i) 
= Left(HMAC_SHA512(c, M, i), 256)⊕ M
M / 0 = CKDpub(M, 0)
M / 1 = CKDpub(M, 1)
M / 2 = CKDpub(M, 2)

M / i = CKDpub(M, i)

详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

· BIP-0032改进提案的好处是,我们只要备份、转移S,即可透过钥匙树(Key Tree)在其他兼容BIP-0032的装置上还原私钥、公钥及地址。

BIP-0039改进提案:
· 有鉴于BIP-0032的S不好记忆,BIP-0039提出S可以透过12组英文单字助记词(Mnemonic Code)来产生。
· 熵(Entropy)函数产生随机的32个16进制字元(128 Bits ~ 256 Bits)ENT(初始熵长度,Initial Entropy Length),再取ENT的位数除以32得到CS(校验和长度,Checksum Length)。
· 注:ENT = Entropy()= 128 + 32 * N Bits,N = 0 ~ 4,这边采Entropy 128 Bits/12 Words来作计算。
ENT = Entropy_128_Bits
CS = Length(ENT)/ 32
· 在ENT右侧串接SHA256(ENT)左边的CS个字元。
X = ENT *(2 ^ CS)+ Left(SHA256(ENT), CS)
· 将X每11 Bits进行切割生成的助记词(Generated Mnemonic Sentence,MS)
MS[ ] = Split(X, 11)
· 因为ENT位数范围为(128 + 32 * N)Bits,N = 0 ~ 4,下表为不同ENT位数时会产生助记词MS数量。

详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

· 以太坊MetaMask钱包是使用当ENT为128位时产生的12组MS,透过查表法,我们可得对映的12组英文单字(或是中文、日文、韩文等)
· 注:对映表可参考此连接。
· 可以将12 ~ 24组的MS + Salt(密码学中加强哈希乱度用)经过2048次的HMAC-SHA512计算后取得BIP-0032所使用的S。
S =(HMAC_SHA512 ^ 2048)(MS + Salt)

详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

BIP-0043改进提案:
· 根据BIP-0032改进提案,将Key Tree的第一级定义为宗旨(Purpose),Purpose值与BIP-00XX改进提按的编号相等,例如BIP-0044中的Purpose = 44。
BIP-0044改进提案中的中的Key Tree
= m / 44′ 
= HKD(m, 44) 
= Left(HMAC_SHA512(c, m, 44))⊕ m
BIP-0044改进提案:
· 根据BIP-0032、BIP-0043的改进提案,将Key Tree的
· 第一级定义为宗旨(Purpose)
· 第二级定义为代币类型(Coin Type)
· 第三级定义为帐户(Account)
· 第四级定义为链的变化(Change)
· 第五级定义为地址索引(Index)
BIP-0044的Key Tree
= CKDpub(CKDpub(HKD(HKD(HKD(m,i),j),n),o),p)
= m / i’ / j’ / n’ / o / p
i = Purpose,i = 44表示BIP-0044。
j = Coin Type,j = 0表示比特币;j = 1表示比特币测试链;j = 60表示以太坊。
n = Account,n = 0表示第一个帐户;n = 1表示第二个帐户。
o = Change,o = 0表示用于收款的外部链(External Chain);o = 1表示用于更改地址的内部链(Internal Chain)。
p = Index,p = 0表示第一组地址;p = 1表示第二组地址。

详解HD Wallet、BIP-0032、BIP-0039、BIP-0043及BIP-0044

结论
本篇介绍了什么是HD Wallet,以及BIP-0032、BIP-0039、BIP-0043、BIP-0044改进提案,而我们可以根据BIP-0044简易的得知:若我们想取得以太坊的第一组帐号中用于收款之第一组地址Key Tree即为m / 44′ / 60′ / 0′ / 0 / 0。