在⽐特币系统中, 我们⽤公钥加密创建⼀个密钥对, ⽤于控制⽐特币的获取。 密钥对包括⼀个私钥, 和由其衍⽣出的唯⼀的公钥。 公钥⽤于接收⽐特币, ⽽私钥⽤于⽐特币⽀付时的交易签名。
公钥和私钥之间的数学关系, 使得私钥可⽤于⽣成特定消息的签名。 此签名可以在不泄露私钥的同时对公钥进⾏验证。
⽀付⽐特币时, ⽐特币的当前所有者需要在交易中提交其公钥和签名( 每次交易的签名都不同, 但均从同⼀个私钥⽣成) 。
⽐特币⽹络中的所有⼈都可以通过所提交的公钥和签名进⾏验证, 并确认该交易是否有效, 即确认⽀付者在该时刻对所交易的⽐特币拥有所有权。
(⼤多数⽐特币钱包⼯具为了⽅便会将私钥和公钥以密钥对的形式存储在⼀起。 然⽽, 公钥可以由私钥计算得到, 所以只存储私钥也是可以的。)
私钥和公钥⼀个⽐特币钱包中包含⼀系列的密钥对, 每个密钥对包括⼀个私钥和⼀个公钥。 私钥( k) 是⼀个数字, 通常是随机选出的。
有了私钥, 我们就可以使⽤椭圆曲线乘法这个单向加密函数产⽣⼀个公钥( K) 。 有了公钥( K) , 我们就可以使⽤⼀个单向加密哈希函数⽣成⽐特币地址( A) 。 在本节中, 我们将从⽣成私钥开始, 讲述如何使⽤椭圆曲线运算将私钥⽣成公钥, 并
最终由公钥⽣成⽐特币地址。 私钥、 公钥和⽐特币地址之间的关系如下图所⽰。
私钥
私钥就是⼀个随机选出的数字⽽已。 ⼀个⽐特币地址中的所有资⾦的控制取决于相应私钥的所有权和控制权。 在⽐特币交易中, 私钥⽤于⽣成⽀付⽐特币所必需的签名以证明资⾦的所有权。 私钥必须始终保持机密, 因为⼀旦被泄露给第三⽅, 相当于该私钥保护之下的⽐特币也拱⼿相让了。 私钥还必须进⾏备份, 以防意外丢失, 因为私钥⼀旦丢失就难以复原, 其所保护的⽐特币也将永远丢失。
⽐特币私钥只是⼀个数字。 你可以⽤硬币、 铅笔和纸来随机⽣成你的私钥: 掷硬币256次, ⽤纸和笔记录正反⾯并转换为0和1, 随机得到的256位⼆进制数字可作为⽐特币钱包的私钥。 该私钥可进⼀步⽣成公钥。
⽣成密钥的第⼀步也是最重要的⼀步, 是要找到⾜够安全的熵源, 即随机性来源。 ⽣成⼀个⽐特币私钥在本质上与“在1到2^256之间选⼀个数字”⽆异。 只要选取的结果是不可预测或不可重复的, 那么选取数字的具体⽅法并不重要。 ⽐特币软件使⽤操作系统底层的随机数⽣成器来产⽣256位的熵( 随机性) 。 通常情况下, 操作系统随机数⽣成器由⼈⼯的随机源进⾏初始化, 也可能需要通过⼏秒钟内不停晃动⿏标等⽅式进⾏初始化。 对于真正的偏执狂, 可以使⽤掷骰⼦的⽅法, 并⽤铅笔和纸记录。
更准确地说, 私钥可以是1和n-1之间的任何数字, 其中n是⼀个常数(n=1.158*1077, 略⼩于2^256) , 并由⽐特币所使⽤的椭圆曲线的阶所定义。要⽣成这样的⼀个私钥, 我们随机选择⼀个256位的数字, 并检查它是否⼩于n-1。 从编程的⻆度来看, ⼀般是通过在⼀个密码学安全的随机源中取出⼀⻓串随机字节, 对其使⽤SHA256哈希算法进⾏运算, 这样就可以⽅便地产⽣⼀个256位的数字。 如果运算结果⼩于n-1, 我们就有了⼀个合适的私钥。 否则, 我们就⽤另⼀个随机数再重复⼀次。
以下是⼀个随机⽣成的私钥( k) , 以⼗六进制格式表⽰( 256位的⼆进制数, 以64位⼗六进制数显⽰, 每个⼗六进制数占4位) :
1E99423A4ED27608A15A2616A2B0E9E52CED330AC530EDCC32C8FFC6A526AEDD⽐特币私钥空间的⼤⼩是2^256, 这是⼀个⾮常⼤的数字。 ⽤⼗进制表⽰的话, ⼤约是1077, ⽽可⻅宇宙被估计只含有1080个原⼦。
公钥通过椭圆曲线乘法可以从私钥计算得到公钥, 这是不可逆转的过程: K = k * G 。 其中 k 是私钥, G 是被称为⽣成点的常数点, ⽽ K 是所得公钥。 其反向运算, 被称为“寻找离散对数”——已知公钥 K 来求出私钥 k ——是⾮常困难的, 就像去试验所
有可能的 k 值, 即暴⼒搜索。
椭圆曲线加密法是⼀种基于离散对数问题的⾮对称( 或公钥) 加密法, 可以⽤对椭圆曲线上的点进⾏加法或乘法运算来表达。
上图是⼀个椭圆曲线的⽰例, 类似于⽐特币所⽤的曲线。
⽐特币使⽤了 secp256k1 标准所定义的⼀条特殊的椭圆曲线和⼀系列数学常数。 该标准由美国国家标准与技术研究院
( NIST) 设⽴。 secp256k1 曲线由下述函数定义, 该函数可产⽣⼀条椭圆曲线:
或 y^2mod p = (x^3 + 7) mod p