基本概念
橢圓曲線數字簽名演算法
橢圓曲線數字簽名演算法(ECDSA)是使用橢圓曲線對數字簽名演算法(DSA)的模擬,該演算法是構成比特幣系統的基石。
私鑰
非公開,擁有者需安全保管。通常是由隨機演算法生成的,說白了,就是一個巨大的隨機整數,256位、32位元組。大小介於1 ~ 0xFFFF FFFF FFFF FFFF FFFF FFFF FFFF FFFE BAAE DCE6 AF48 A03B BFD2 5E8C D036 4141之間的數,都可以認為是一個合法的私鑰。於是,除了隨機方法外,採用特定演算法由固定的輸入,得到32位元組輸出的演算法就可以成為得到私鑰的方法。於是,便有了迷你私鑰(Mini Privkey),原理很簡單,例如,採用SHA256的一種實現:
private key = SHA256(<passphase>)
迷你私鑰存在安全問題,因為輸入集合太小,易被構造常見組合的彩虹表暴力破解,所以通常還是使用系統隨機生成的比較好,無安全隱患。
公鑰
公鑰與私鑰是相對應的,一把私鑰可以推出唯一的公鑰,但公鑰卻無法推導出私鑰。公鑰有兩種形式:壓縮與非壓縮。
早期比特幣均使用非壓縮公鑰,現大部分客戶端已默認使用壓縮公鑰。這個貌似是比特幣系統一個長得像feature的bug,早期人少活多代碼寫得不夠精細,openssl庫的文檔又不足夠好,導致Satoshi以為必須使用非壓縮的完整公鑰,後來大家發現其實公鑰的左右兩個32位元組是有關聯的,左側(X)可以推出右側(Y)的平方值,有左側(X)就可以了。
現在系統里兩種方式共存,應該會一直共存下去。兩種公鑰的首個位元組為標識位,壓縮為33位元組,非壓縮為65位元組。以0x04開頭為非壓縮,0x02/0x03開頭為壓縮公鑰,0x02/0x03的選取由右側Y開方後的奇偶決定。
壓縮形式可以減小Tx/Block的體積,每個Tx Input減少32位元組。
簽名
使用私鑰對數據進行簽署(Sign)會得到簽名(Signature)。通常會將數據先生成Hash值,然後對此Hash值進行簽名。簽名(signature)有兩部分組成: R + S。由簽名(signature)與Hash值,便可以推出一個公鑰,驗證此公鑰,便可知道此簽名是否由公鑰對應的私鑰簽名。
通常,每個簽名會有三個長度:73、72、71,符合校驗的機率為25%、50%、25%。所以每次簽署後,需要找出符合校驗的簽名長度,再提供給驗證方。
地址
地址是為了人們交換方便而弄出來的一個方案,因為公鑰太長了(130字元串或66字元串)。地址長度為25位元組,轉為base58編碼後,為34或35個字元。base58是類似base64的編碼,但去掉了易引起視覺混淆的字元,又在地址末尾添加了4個位元組校驗位,保障在人們交換個別字元錯誤時,也能夠因地址校驗失敗而制止了誤操作。
由於存在公鑰有兩種形式,那麼一個公鑰便對應兩個地址。這兩個地址都可由同一私鑰簽署交易。
公鑰生成地址的演算法:
下圖是非壓縮公鑰生成地址的過程:
對於壓縮公鑰生成地址時,則只取公鑰的X部分即可。
推導關係
三者推導關係:私鑰 >> 公鑰 >> 兩個地址。過程均不可逆。擁有私鑰便擁有一切,但通常為了方便,會把對應的公鑰、地址也存儲起來。