Alert Source Discuss
🚧 Stagnant Standards Track: Core

EIP-665: 为 Ed25519 签名验证添加预编译合约

Authors Tobias Oberstein <tobias.oberstein@crossbario.io>
Created 2018-03-25

概要

通过向 EVM 添加用于 Ed25519 签名验证的预编译合约,从而普遍支持在智能合约中进行性能良好且成本低廉的 Ed25519 密码签名验证。

摘要

显然,在 EVM 字节码中可以实现 Ed25519 密码签名的验证。然而,gas 成本将非常高,并且计算量很大,因为 Ed25519 所需的紧凑的、宽字操作密集型代码与 EVM 字节码模型不太匹配。

在预编译合约中添加本地编译函数到 EVM 可以解决成本和性能问题。

动机

Ed25519 和 Ed448(即使用 Curve25519 或 Curve448 的 EdDSA)是 IETF 推荐标准 (RFC7748),具有一些吸引人的特性:

  • Ed25519 旨在以大约 128 位的安全级别运行,而 Ed448 旨在以大约 224 位的安全级别运行
  • EdDSA 使用小的公钥(32 或 57 个八位字节)和签名(64 或 114 个八位字节),分别用于 Ed25519 和 Ed448
  • Ed25519/Ed448 的设计使得更容易生成快速、恒定时间(抗定时攻击)和通常抗侧信道攻击的实现

尽管只出现了几年,在斯诺登事件之后,这些曲线 已经在各种协议和系统中获得了广泛使用

  • TLS / ECDH(E) (会话密钥)
  • TLS / x.509 (客户端和服务器证书)
  • DNSSEC(区域签名)
  • OpenSSH (用户密钥)
  • GNUPG/OpenPGP (用户密钥)
  • OpenBSD Signify (软件签名)

在智能合约中进行 Ed25519 签名验证的一个动机是关联使用 Ed25519 的现有链下系统、记录或帐户(如上所述)与区块链地址,或通过允许使用 Ed25519(仅限)对数据进行签名来委派,然后将此 Ed25519 签名的数据匿名地(通过任何 Eth 发送者地址)提交到区块链,让合约检查交易的 Ed25519 签名。

另一个动机是在以太坊智能合约中处理基于外部的、Ed25519 权益证明区块链。

当交易包含带有 Ed25519 签名的数据时,这证明了以太坊交易的发送者也控制着私钥(和数据),这允许合约在区块链和外部系统或帐户之间建立关联,并且外部系统建立相反的关系。

例如,合约可能会检查提交给以太坊交易的、Ed25519 签名的某个数据,如当前区块号。这向合约证明,发送者同时拥有以太坊私钥和 Ed25519 私钥,因此合约将接受两者之间的关联。这又可以成为各种强大应用的根本依据,因为现在一个潜在的加密货币持有密钥所有者已经证明可以控制一些外部链下系统或帐户,例如 DNS 服务器、DNS 域、集群节点等等。

规范

如果 block.number >= CONSTANTINOPLE_FORK_BLKNUM,则为 Ed25519 签名验证添加一个预编译合约 (ED25519VFY)。

该提案添加了一个新的预编译函数 ED25519VFY,具有以下输入和输出。

ED25519VFY 接受 128 个八位字节作为 输入

  1. message: 已签名的 32 字节消息
  2. public key: 签名者的 32 字节 Ed25519 公钥
  3. signature: 64 字节 Ed25519 签名

ED25519VFY 返回 4 个八位字节作为 输出

  • 0x00000000 如果签名有效
  • 任何非零值表示签名验证失败

地址

ED25519VFY 的地址是 0x9

Gas 成本

ED25519VFY 的 Gas 成本是 2000

理由

拟议的 ED25519VFY 函数将签名者的公钥作为调用参数,因为使用 Ed25519,我认为不可能仅从签名和消息中推导出签名者的公钥。

拟议的 ED25519VFY 函数使用零返回值来表示成功,因为这允许通过返回值来区分不同的错误,因为所有非零返回值都表示验证失败。

ECRECOVER 的 gas 成本为 3000。由于 Ed25519 在计算上更便宜,因此 gas 价格应该更低。

向后兼容性

由于拟议的预编译合约部署在保留的 (<255) 且之前未使用的地址上,因此该提案的实现不应引入任何向后兼容性问题。

测试用例

Ed25519 的测试向量可以在此 IETF ID 中找到 https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-6。

更多测试向量可以在 NaCl 的回归测试中找到(参见参考资料)。

实现

libsodium

libsodium 是一个成熟的、高质量的 Ed25519 的 C 实现,具有多种语言的绑定。

此外,据我所知,并且截至今天 2018/04,libsodium 是唯一一个通过了 安全评估 的 Ed25519 实现。

为了最大限度地降低共识失败的风险,该提案建议使用 libsodium 在所有以太坊客户端实现中添加预编译。

注意:作为 libsodium 的替代方案,我研究了 HACL,一个用 F*(一种 ML 方言)实现的 Ed25519,可以将其转换为 C,并且经过正式验证,可以保证生成的 C 代码的功能正确性和内存安全性。但是,这是新的,并且与 libsodium 相比,libsodium 是一个“已知的”东西,因此仍然存在风险。

libsodium 绑定

以下是本提案推荐的四个以太坊客户端的 libsodium 语言绑定的概述:

| 客户端 | 语言 | libsodium 绑定 | —————|———-|——————–| | Geth | Go | 使用带有 C libsodium 的 cgo | | Parity | Rust | sodiumoxide | | PyEthereum | Python | PyNaCl | | cpp-ethereum | C++ | libsodium | —————————————————————————-

PR

此提案的实现位于此处:

  1. go-ethereum PR #16453
  2. pyethereum PR #862
  3. parity PR #8330
  4. cpp-ethereum PR #4945

参考

  • RFC7748 - 用于安全性的椭圆曲线 https://tools.ietf.org/html/rfc7748
  • Ed25519 的定义: https://ed25519.cr.yp.to/ed25519-20110926.pdf
  • Ed25519 - 高速高安全性签名: https://ed25519.cr.yp.to/
  • NaCl - 网络和密码学库: https://nacl.cr.yp.to/sign.html
  • NaCl 密码库(包含 Ed25519): https://ianix.com/pub/ed25519-deployment.html
  • Ed25519 的测试向量: https://tools.ietf.org/html/draft-josefsson-eddsa-ed25519-03#section-6
  • NaCl 回归测试: https://ed25519.cr.yp.to/python/sign.py 和 https://ed25519.cr.yp.to/python/sign.input
  • 关于仅从签名+消息(单独)中恢复公钥的能力:https://crypto.stackexchange.com/questions/9936/what-signature-schemes-allow-recovering-the-public-key-from-a-signature
  • Bernstein, D., “Curve25519: new Diffie-Hellman speed records”, DOI 10.1007/11745853_14, February 2006, https://cr.yp.to/ecdh.html
  • Hamburg, M., “Ed448-Goldilocks, a new elliptic curve”, June 2015, https://eprint.iacr.org/2015/625>
  • RFC8080: 用于 DNSSEC 的 Edwards 曲线数字安全算法 (EdDSA) (https://datatracker.ietf.org/doc/html/rfc8080)

版权

通过 CC0 放弃版权及相关权利。

Citation

Please cite this document as:

Tobias Oberstein <tobias.oberstein@crossbario.io>, "EIP-665: 为 Ed25519 签名验证添加预编译合约 [DRAFT]," Ethereum Improvement Proposals, no. 665, March 2018. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-665.