ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

深入解析 EIP-665:为 EVM 增加 Ed25519 签名验证预编译合约

深入解析 EIP-665:为 EVM 增加 Ed25519 签名验证预编译合约 深入解析 EIP-665为 EVM 增加 Ed25519 签名验证预编译合约【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs本文章节与核心规范均基于 EIPS/eip-665.md 编写仓库内其余 EIP 文档如 EIP-1352、EIP-1109、EIP-2046 等仅用于补充预编译合约机制的背景说明帮助读者更完整地理解该提案在以太坊预编译体系中的位置。导读EIP-665Add precompiled contract for Ed25519 signature verification是一份以太坊核心Core类标准提案主张在 EVM 中加入一个名为ED25519VFY的原生预编译合约用于在智能合约中高效、廉价地完成 Ed25519 数字签名验证。本篇文章将带你完整梳理该提案的动机、输入输出规范、地址与 gas 定价、实现建议与测试向量来源并结合本仓库中的其他 EIP 文档解释预编译合约Precompiled Contract在以太坊协议中的定位与调用成本问题使读者既能在合约层面理解“如何用”也能在协议层面理解“为什么这样设计”。一、为什么需要为 EVM 增加 Ed25519 预编译合约1.1 问题本质EVM 字节码不适合做 Ed25519Ed25519 签名验证在理论上完全可以仅用 EVM 字节码实现但代价极高。EIP-665 明确指出Ed25519 这类算法要求紧凑tight、宽字wide word运算密集的代码形态而这与 EVM 字节码的模型并不匹配因此若以 Solidity / 字节码方式实现gas 开销会非常高昂计算耗时也很大EIPS/eip-665.md。解决方案便是预编译合约Precompiled Contract将 Ed25519 验证实现为客户端原生编译的函数在固定地址上以合约调用的形式暴露给 EVM。这样既解决了性能问题也大幅降低了 gas 成本。1.2 Ed25519/Ed448 的密码学优势Ed25519及 Ed448即基于 Curve25519/Curve448 的 EdDSA是 IETF 推荐算法RFC 7748其核心吸引力包括安全强度Ed25519 定位于约 128-bit 安全级别Ed448 约 224-bit密钥与签名体积小Ed25519 公钥 32 字节、签名 64 字节Ed448 公钥 57 字节、签名 114 字节实现友好Ed25519/Ed448 设计上便于产出快速、常数时间可抵抗计时侧信道攻击且整体抗侧信道的实现。正因如此该算法在斯诺登事件之后被广泛部署于各类协议与系统EIPS/eip-665.mdTLS / ECDH(E)会话密钥TLS / x.509客户端与服务器证书DNSSEC区域签名OpenSSH用户密钥GNUPG/OpenPGP用户密钥OpenBSD Signify软件签名1.3 智能合约中的两个核心动机EIP-665 给出了两个在链上引入 Ed25519 验证的直接动机EIPS/eip-665.md关联associate与委托delegate让链上合约能够将链下使用 Ed25519 的系统、记录或账户如 DNS 服务器、DNS 域名、集群节点等与区块链地址建立关联。具体流程为数据仅用 Ed25519 签名然后由任意以太坊发送地址匿名提交上链合约负责校验该 Ed25519 签名。当交易携带的数据带有有效 Ed25519 签名时即可证明以太坊交易发送者同时掌握了以太坊私钥与 Ed25519 私钥从而建立双向关联——这可以成为许多强大应用如证明某加密资产持有者掌控某个链外系统的信任根锚点。处理外部 PoS 区块链在以太坊智能合约中处理外部基于 Ed25519 的权益证明PoS链的数据。一个典型的示例合约检查提交到以太坊交易中的 Ed25519 签名数据例如当前区块号。签名有效即证明发送者同时持有两条私钥合约便接受两者之间的关联。二、规范详解ED25519VFY 的接口与参数2.1 激活条件与地址EIP-665 规范要求EIPS/eip-665.md当block.number CONSTANTINOPLE_FORK_BLKNUM君士坦丁堡分叉区块高度时启用名为ED25519VFY的预编译合约地址0x9即0x0000000000000000000000000000000000000009gas 成本固定2000。关于地址0x9的选用本仓库中的 EIPS/eip-1352.md 提供了协议背景地址范围0x0000...0000到0x0000...ffff被保留给预编译合约与系统合约。0x9位于该保留区间内且此前未被使用因此新增它不会带来向后兼容问题。2.2 输入128 字节定长编码ED25519VFY接收恰好128 个八位组octets的输入EIPS/eip-665.md序号字段长度说明1message消息32 字节被签名的消息2public key公钥32 字节签名者的 Ed25519 公钥3signature签名64 字节Ed25519 签名三者按顺序拼接[32 bytes message][32 bytes public key][64 bytes signature]。2.3 输出4 字节结果码ED25519VFY返回恰好4 个八位组EIPS/eip-665.md0x00000000签名有效任何非零值表示签名验证失败。这种“零表示成功”的设计是刻意为之由于所有非零返回值都代表失败调用方可以依据不同的非零值区分不同错误类型。2.4 为何公钥作为入参而不是推导EIP-665 在 Rationale 部分解释了设计取舍EIPS/eip-665.md与某些签名方案不同Ed25519 无法仅从签名与消息推导出签名者的公钥因此ED25519VFY必须将公钥作为调用参数显式传入。2.5 gas 定价的推导依据作为对比EIP-665 指出ECRECOVER的 gas 成本为 3000由于 Ed25519 在计算上更廉价其 gas 定价应当更低因此定为2000EIPS/eip-665.md。需要补充说明的是实际调用预编译合约的总成本并非只有预编译自身定价。本仓库中的 EIPS/eip-1109.md 指出普通CALL指令本身就要消耗 700 gas 的基础成本这使得当时有效总成本低于 700的预编译难以存在而 EIPS/eip-2046.md 则提议将针对预编译的STATICCALL基础成本从 700 降至 40。因此即便ED25519VFY自身定价 2000实际总开销还需叠加调用指令的基础成本——这也解释了为何 EIP-665 之后仍有一系列针对预编译调用成本的优化提案如 EIP-1109、EIP-2046。这些上下文能帮助你更准确地评估“2000 gas”在真实交易中的含义。三、向后兼容性分析由于ED25519VFY部署在保留的 255且此前未使用的地址0x9上实现该提案不应引入任何向后兼容问题EIPS/eip-665.md。这一论断与 EIPS/eip-1352.md 的保留地址区间约定一致主网上没有任何常规合约曾创建在这些地址上。四、测试用例EIP-665 建议使用以下来源作为测试向量EIPS/eip-665.mdIETF 草案《EdDSA for Ed25519》第 6 节的 Ed25519 测试向量NaCl 库的回归测试sign.py与sign.input。这些外部测试向量用于验证各客户端实现与官方参考实现的一致性是确保不同以太坊客户端之间共识一致的关键依据。五、实现方案推荐 libsodium 及其客户端绑定5.1 为什么选 libsodiumEIP-665 推荐在所有以太坊客户端实现中统一使用libsodium来添加该预编译EIPS/eip-665.mdlibsodium 是成熟、高质量的 Ed25519 C 语言实现拥有众多语言的绑定截至提案撰写时2018/04libsodium 是唯一经过独立**安全评估Security Assessment**的 Ed25519 实现全客户端统一实现可最大限度降低共识失败风险。提案作者同时考察过 HACL——一种以 F* 语言编写、可转译为 C 且经过形式化验证功能正确性与内存安全的 Ed25519 实现但因其较新、相比“已知可靠”的 libsodium 更具风险而未被推荐。5.2 四个主流客户端与 libsodium 绑定提案为四类以太坊客户端给出了推荐的语言绑定EIPS/eip-665.md客户端语言libsodium 绑定GethGo通过 cgo 调用 C 版 libsodiumParityRustsodiumoxidePyEthereumPythonPyNaClcpp-ethereumClibsodium5.3 各客户端实现 PR提案列出了各客户端对应的实现 Pull RequestEIPS/eip-665.mdgo-ethereum PR #16453、pyethereum PR #862、parity PR #8330、cpp-ethereum PR #4945。六、合约侧调用方式与注意事项虽然 EIP-665 正文未给出 Solidity 示例但结合本仓库其他预编译类 EIP 的调用范式可以给出合约侧的通用调用思路。例如 EIPS/eip-152.mdBLAKE2 预编译展示了如何在 Solidity 中用内联汇编通过staticcall调用预编译合约assembly { if iszero(staticcall(not(0), 0x09, add(args, 32), inputLen, output, 0x40)) { revert(0, 0) } }参照该模式调用ED25519VFY地址0x9时按[32B message][32B public key][64B signature]顺序拼接 128 字节输入使用staticcall指定目标地址0x9、输入长度 128、输出缓冲区 4 字节读取返回的 4 字节结果0x00000000表示验证通过非零表示失败。注意调用时必须保证传入的数据长度与编码严格符合规范且应以**只读调用staticcall**执行因为预编译合约不改变状态。七、协议背景预编译合约机制一览为了让读者更透彻地理解 EIP-665 在整个 EVM 体系中的位置这里汇总本仓库中与预编译机制直接相关的几份 EIPEIP主题与 EIP-665 的关联EIPS/eip-196.mdalt_bn128 椭圆曲线加法与标量乘法预编译地址 0x6、0x7同为密码学预编译展示“固定输入编码 固定输出长度”的规范风格EIPS/eip-197.mdalt_bn128 配对检查预编译与 EIP-196 配合实现 zkSNARK 验证EIPS/eip-198.md大整数模幂预编译地址 0x5说明 gas 可由输入长度动态推导的另一种定价模式EIPS/eip-1109.mdPRECOMPILEDCALL操作码移除预编译的 CALL 成本针对预编译调用总成本700 gas 基础费的优化EIPS/eip-2046.md降低对预编译STATICCALL的 gas 成本700→40进一步降低预编译使用门槛EIPS/eip-1352.md指定预编译/系统合约的保留地址区间为地址0x9的合法性提供协议依据EIPS/eip-152.mdBLAKE2F压缩函数预编译地址 0x9 的争夺者提供 Solidity 侧staticcall调用预编译的完整示例其中特别值得注意地址0x9同样是 EIPS/eip-152.mdBLAKE2 预编译所申请使用的地址。两份提案都瞄准了0x9而实际以太坊主网最终启用的是 BLAKE2 预编译EIP-152 状态为 FinalEIP-665 状态为 Stagnant停滞——这一事实清晰地说明在预编译地址稀缺的保留区间内同一地址上的提案之间存在竞争关系最终能否落地取决于硬分叉的实际决策。此信息属于本仓库文件可验证的范围两份文档的地址声明与状态字段可作为理解 EIP-665 现状的背景参考。八、状态说明与阅读指引本仓库中 EIPS/eip-665.md 的 front matter 表明其状态为Stagnant停滞类型为 Standards Track / Core创建于 2018-03-25作者为 Tobias ObersteinCrossbar.io。这意味着该提案并未进入最终激活状态阅读时应将其视为“已完整规范化的历史提案”而非“当前生效的协议特性”。文中提到的分叉常量CONSTANTINOPLE_FORK_BLKNUM、外部测试向量链接、客户端绑定仓库及 PR 链接均为原文档所载信息读者如需追溯实现细节应以提案正文EIPS/eip-665.md及对应客户端当时的代码为准。若要在本地复现验证逻辑可参考 libsodium 的 Ed25519 APIcrypto_sign_verify_detached类函数配合 IETF/NaCl 测试向量进行比对合约侧则以本仓库 EIPS/eip-152.md 的 Solidity 汇编调用范式为模板。总结EIP-665 为“在智能合约中验证 Ed25519 签名”这一需求给出了完整、可直接实现的协议规范固定地址0x9、128 字节定长输入、4 字节结果码输出、2000 gas 定价并以 libsodium 作为跨客户端统一实现以控制共识风险。尽管该提案最终停滞、其地址被 BLAKE2 预编译EIP-152占据但它在密码学预编译的接口设计定长编码、零值成功约定、gas 定价逻辑对标 ECRECOVER 并考虑计算成本以及多客户端实现协作方式上仍是理解以太坊预编译机制演进的重要文献。结合本仓库中的 EIPS/eip-1352.md、EIPS/eip-1109.md、EIPS/eip-2046.md 等文档你可以进一步构建起关于 EVM 预编译体系的完整知识图谱。【免费下载链接】EIPsThe Ethereum Improvement Proposal repository项目地址: https://gitcode.com/GitHub_Trending/ei/EIPs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表