Alert Source Discuss
Standards Track: Networking

EIP-627: Whisper 规范

Authors Vlad Gluhovsky <gluk256@gmail.com>
Created 2017-05-05

摘要

本 EIP 描述了 ÐΞVp2p Wire Protocol 中 Whisper 消息的格式。 本 EIP 应该替代 现有规范。 关于 Whisper 的更详细文档可以在 这里 找到。

动机

有必要指定 Whisper 消息的标准,以确保不同 Whisper 客户端的向前兼容性。

规范

所有作为 ÐΞVp2p Wire Protocol 数据包发送的 Whisper 消息都应该是 RLP 编码的数据数组,其中包含两个对象:整数数据包代码,后跟另一个对象(其类型取决于数据包代码)。

如果 Whisper 节点不支持特定的数据包代码,它应该忽略该数据包而不产生任何错误。

数据包代码

为 Whisper 协议保留的消息代码:0 - 127。 具有未知代码的消息必须被忽略,以实现未来版本的前向兼容性。

Whisper 子协议应支持以下数据包代码:

EIP 名称 整数值
  状态 0
  消息 1
  PoW 要求 2
  布隆过滤器 3

以下消息代码是可选的,但它们被保留用于特定目的。

EIP 名称 整数值
  P2P 请求 126
  P2P 消息 127

数据包格式和用法

状态 [0]

此数据包包含两个对象:整数消息代码 (0x00),后跟一个值列表:整数版本、浮点 PoW 要求和布隆过滤器,按此顺序。 布隆过滤器参数是可选的; 如果缺少或为 nil,则该节点被认为是完整节点(即接受所有消息)。 PoW 和布隆过滤器的格式请参见下文(消息代码 2 和 3)。

状态消息应在初始握手之后和任何其他消息之前发送。

消息 [1, whisper_envelopes]

此数据包包含两个对象:整数消息代码 (0x01),后跟一个 Whisper 信封列表(可能为空)。

此数据包用于发送标准 Whisper 信封。

PoW 要求 [2, PoW]

此数据包包含两个对象:整数消息代码 (0x02),后跟一个 PoW 的浮点值。 该值是 64 位浮点数的 IEEE 754 二进制表示形式。 不允许使用 qNAN、sNAN、INF 和 -INF 值。 也不允许使用负值。

Whisper 节点使用此数据包来动态调整其各自的 PoW 要求。 此消息的接收者不应再传递 PoW 低于此消息中指定的发送者消息。

PoW 定义为找到当前 BestBit(哈希中前导零位的数量)所需的平均迭代次数,除以消息大小和 TTL:

PoW = (2**BestBit) / (size * TTL)

PoW 计算:

fn short_rlp(envelope) = rlp of envelope, excluding env_nonce field.
fn pow_hash(envelope, env_nonce) = sha3(short_rlp(envelope) ++ env_nonce)
fn pow(pow_hash, size, ttl) = 2**leading_zeros(pow_hash) / (size * ttl)

其中 size 是完整 RLP 编码的信封的大小。

布隆过滤器 [3, bytes]

此数据包包含两个对象:整数消息代码 (0x03),后跟任意大小的字节数组。

Whisper 节点使用此数据包来共享他们对具有特定主题的消息的兴趣。

布隆过滤器用于识别对等方的多个主题,而不会(过多地)泄露对哪些主题有兴趣。 可以通过添加位来保持对信息内容(以及因此过滤器的效率)的精确控制。

Bloom 由对多个 bloom 主题执行按位 OR 运算形成。 bloom 函数获取主题并将它们投影到 512 位切片上。 对于每个 bloom 的主题,最多标记三个位。

投影函数定义为从 4 字节切片 S 到 512 位切片 D 的映射; 为了便于解释,S 将取消引用为字节,而 D 将取消引用为位。

LET D[*] = 0
FOREACH i IN { 0, 1, 2 } DO
LET n = S[i]
IF S[3] & (2 ** i) THEN n += 256
D[n] = 1
END FOR

可选

P2P 请求 [126, whisper_envelope]

此数据包包含两个对象:整数消息代码 (0x7E),后跟一个 Whisper 信封。

此数据包用于发送 Dapp 级点对点请求,例如,Whisper 邮件客户端从 Whisper 邮件服务器请求旧消息。

P2P 消息 [127, whisper_envelope]

此数据包包含两个对象:整数消息代码 (0x7F),后跟一个 Whisper 信封。

此数据包用于发送不应进一步转发的点对点消息。 例如,Whisper 邮件服务器可能会使用它来传递旧的(过期的)消息,否则这是不允许的。

Whisper 信封

信封是以下格式的 RLP 编码结构:

[ Expiry, TTL, Topic, Data, Nonce ]

Expiry: 4 个字节(以秒为单位的 UNIX 时间)。

TTL: 4 个字节(生存时间,以秒为单位)。

Topic: 4 个字节的任意数据。

Data: 任意大小的字节数组(包含加密消息)。

Nonce: 8 个字节的任意数据(用于 PoW 计算)。

消息数据字段的内容(可选)

本节概述了数据字段的可选描述,以设置示例。 稍后可能会将其移至单独的 EIP。

它仅在您要解密传入消息时才相关,但是如果您只想发送消息,则任何其他格式都将完全有效,并且必须转发给对等方。

数据字段包含信封的加密消息。 在对称加密的情况下,它还包含附加的 Salt(又名 AES Nonce,12 个字节)。 纯文本(未加密)有效负载由以下串联字段组成:标志、辅助字段、有效负载、填充和签名(按此顺序)。

flags: 1 byte; first two bits contain the size of auxiliary field, third bit indicates whether the signature is present.

auxiliary field: up to 4 bytes; contains the size of payload.

payload: byte array of arbitrary size (may be zero).

padding: byte array of arbitrary size (may be zero).

signature: 65 bytes, if present.

salt: 12 bytes, if present (in case of symmetric encryption).

那些无法解密消息数据的人也无法访问签名。 如果提供了签名,则签名是使用发起者身份的密钥对未加密数据的 Keccak-256 哈希进行 ECDSA 签名。 签名被序列化为 SECP-256k1 ECDSA 签名的 RSV 参数的串联,按该顺序。 RS 都是大端编码的、固定宽度的 256 位无符号整数。 V 是一个 8 位大端编码的、非规范化的值,应该是 27 或 28。

引入填充字段是为了对齐消息大小,因为仅消息大小可能会泄露重要的元信息。 填充可以是任意大小。 但是,建议加密前数据字段的大小(不包括 Salt)(即纯文本)应该是 256 字节的倍数。

有效负载加密

非对称加密使用带有 SECP-256k1 公钥的标准椭圆曲线集成加密方案。

对称加密使用带有随机 96 位 nonce 的 AES GCM 算法。

理由

数据包代码 0x00 和 0x01 已经在所有 Whisper 版本中使用。

数据包代码 0x02 对于 Whisper 的未来发展是必要的。 它将提供实时调整 PoW 要求的可能性。 最好允许网络自我管理,而不是硬编码任何最小 PoW 要求的特定值。

数据包代码 0x03 对于网络的可扩展性是必要的。 如果流量过多,节点将只能请求和接收它们感兴趣的消息。

数据包代码 0x7E 和 0x7F 可用于实现 Whisper 邮件服务器和客户端。 如果没有 P2P 消息,将无法传递旧消息,因为它们将被识别为已过期,并且对等方将因违反 Whisper 协议而被断开连接。 当不可能花费时间在 PoW 上时,它们可能对其他目的有用,例如,如果证券交易所想要提供有关最新交易的实时提要。

向后兼容性

此 EIP 与 Whisper 版本 6 兼容。任何未实现某些数据包代码的客户端都应正常忽略具有这些代码的数据包。 这将确保向前兼容性。

实现

Whisper (v.6) 的 golang 实现已经使用数据包代码 0x00 - 0x03。 Parity 的 v.6 实现也将使用代码 0x00 - 0x03。 代码 0x7E 和 0x7F 被保留,但仍未使用,留给 Whisper 邮件服务器的自定义实现。

版权

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

Citation

Please cite this document as:

Vlad Gluhovsky <gluk256@gmail.com>, "EIP-627: Whisper 规范," Ethereum Improvement Proposals, no. 627, May 2017. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-627.