ERC-2098: 紧凑签名表示
以太坊签名的紧凑表示。
Authors | Richard Moore (@ricmoo), Nick Johnson <nick@ethereum.org> |
---|---|
Created | 2019-03-14 |
Requires | EIP-2 |
摘要
secp256k1 曲线允许计算签名摘要的公钥,当与签名结合时,它被隐式地用于 从外部拥有的帐户建立交易的来源,以及在 EVM 合约中链上进行,例如,在元交易和 多重签名合约中。
目前,签名需要 65 字节来表示,当对齐到 256 位字时,需要 96 字节(注入 31 个零字节)。 RLP 编码交易中的 yParity 也需要(平均)1.5 字节。 使用紧凑签名,这可以减少到 64 字节,字对齐时仍然是 64 字节,并且在 RLP 编码交易的情况下, 节省了 yParity 所需的 1.5 字节。
动机
紧凑表示的动机是简化客户端代码中处理交易,降低 gas 成本并减少交易大小。
规范
secp256k1 签名由 3 个参数组成:r
、s
和 yParity
。
r
表示曲线上的 x
分量(可以从中计算 y
),s
表示私钥签名的挑战解。
由于椭圆曲线的对称性,需要一个 yParity
,它指示 2 个可能的解决方案中哪一个是预期的,
通过指示其奇偶性。
要创建紧凑表示,需要两个关键观察结果。
首先,yParity
参数始终为 0 或 1(规范上使用的值历史上是 27 和 28,因为这些值与比特币中使用的其他二进制前缀没有冲突)。
其次,由于使用规范签名来翻转解决方案奇偶性以防止负值,因此 s
参数的最高位始终为 0,
这是作为Homestead 中的一个约束引入的。
因此,我们可以劫持 s
参数中的最高位来存储 yParity
的值,从而得到:
[256-bit r value][1-bit yParity value][255-bit s value]
Python 中的示例实现
# Assume yParity is 0 or 1, normalized from the canonical 27 or 28
# 假设 yParity 为 0 或 1,从规范的 27 或 28 归一化
def to_compact(r, s, yParity):
return {
"r": r,
"yParityAndS": (yParity << 255) | s
}
def to_canonical(r, yParityAndS):
return {
"r": r,
"s": yParityAndS & ((1 << 255) - 1),
"yParity": (yParityAndS >> 255)
}
原理
所提出的紧凑表示形式在客户端和 Solidity 中都很容易组合和分解,因此可以轻松(且直观地)支持它, 同时减少交易大小和 gas 成本。
向后兼容性
紧凑表示形式与规范签名不冲突, 因为它使用 2 个参数(r, yParityAndS)并且长度为 64 字节,而规范签名涉及 3 个单独的参数(r, s, yParity)并且长度为 65 字节。
测试用例
Private Key: 0x1234567890123456789012345678901234567890123456789012345678901234
Message: "Hello World"
Signature:
r: 0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90
s: 0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064
v: 27
Compact Signature:
r: 0x68a020a209d3d56c46f38cc50a33f704f4a9a10a59377f8dd762ac66910e9b90
yParityAndS: 0x7e865ad05c4035ab5792787d4a0297a43617ae897930a6fe4d822b8faea52064
Private Key: 0x1234567890123456789012345678901234567890123456789012345678901234
Message: "It's a small(er) world"
Signature:
r: 0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76
s: 0x139c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793
v: 28
Compact Signature:
r: 0x9328da16089fcba9bececa81663203989f2df5fe1faa6291a45381c81bd17f76
yParityAndS: 0x939c6d6b623b42da56557e5e734a43dc83345ddfadec52cbe24d0cc64f550793
参考实现
ethers.js 库在 v5 中支持此功能,
作为拆分签名(即 sig._vs
)的非官方属性,但应被视为内部属性,可能会根据社区的判断进行更改
以及对此 EIP 的任何更改。
安全注意事项
此 EIP 不会引入其他安全问题。
版权
在 CC0 下放弃版权及相关权利。
Citation
Please cite this document as:
Richard Moore (@ricmoo), Nick Johnson <nick@ethereum.org>, "ERC-2098: 紧凑签名表示," Ethereum Improvement Proposals, no. 2098, March 2019. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-2098.