术语表 /开发者参考
点函数
- 点函数是什么?
- 点函数通过将 secp256k1 的生成元点乘以私钥这一数值,把私钥转换为公钥,它是所有比特币地址赖以构建的单向步骤。
规定于 BIP-32。
BIP32 为这一运算命名为 point(p),因为分层密钥派生几乎在每一行都要引用它。将曲线的固定生成元乘以一个256位的秘密数,得到的坐标对可以安全公开;若要从该坐标对恢复这个秘密数,就必须在一个78位数字的空间中求解离散对数。您的钱包每个地址只运行一次该函数,从不需要反向运行。
运作方式
点函数是椭圆曲线乘法,其两个输入之一永久固定。
比特币使用 secp256k1 曲线,该曲线在一个大素数域上由方程 y 的平方等于 x 的立方加7定义,并由 SEC 2文件而非 NIST 标准化。该曲线带有一个生成元点 G,所有实现都将其硬编码,群的阶 n 的值略小于2的256次方。私钥是从1到 n 减1之间的任意整数。该函数借助倍点与加点的阶梯算法,把 G 与自身相加相应次数,在远不足一毫秒内即可完成,而不需要宇宙的年龄那么久。
反向运算则是整个安全假设之所在。给定得到的点,目前没有任何已公布的方法能比大约群规模的平方根更快地恢复乘数,这意味着工作量约为2的128次方次运算。即使地址被重复使用、被公开或被持有数十年,这一切也不会改变。
有一个性质使分层钱包成为可能。点乘对加法满足分配律,因此 a 加 b 的点等于 a 的点与 b 的点相加。给私钥加上一个调整值,对应的公钥就会偏移该调整值所对应的点,任何人都可以在不持有私钥的情况下计算这一偏移量。非硬化的 BIP32 派生依赖于这一恒等式,Taproot 输出密钥也是如此,它是一个内部密钥加上对脚本树的承诺后偏移得到的密钥。
在哪里会遇到它
每当钱包向您显示一个新的收款地址时,点函数都会运行一次。
这也是扩展公钥本身就有用的原因。将 xpub 交给在线商店或仅观察的手机,该设备就可以通过调整公钥为每笔付款生成新地址,而设备上任何地方都不存在私钥。硬件钱包则从另一侧利用同样的不对称性:秘密数从不离开芯片,只有得到的点通过数据线传回。
这一性质也有其风险的一面。由于这种关系是加法式且公开的,扩展公钥再加上一个泄露的非硬化子私钥,任何人都能恢复父私钥,进而恢复整个分支。这就是账户层级的派生采用硬化的原因,也是泄露的 xpub 会造成隐私灾难而不是立即被盗的原因。
点函数 vs 压缩公钥
点函数产生的是一个数学对象;压缩公钥是把该对象写下来的一种方式。一个点是一对坐标,每个坐标32字节。压缩形式舍弃 y 坐标,只保留一个一字节的前缀,记录它是偶数还是奇数,共33字节。未压缩形式则把两个坐标完整写出,共65字节。Taproot 的 x-only 形式保留32字节,完全没有前缀。它们描述的都是同一个点,但每种编码经哈希后得到的地址各不相同,因此导入旧密钥时若压缩标志有误,余额会显示为零,而比特币实际上原封不动地留在另一个地址上。