Skip to main content

意图签名

在 Sui 中,意图是一个紧凑的结构,作为签名所承诺的消息的域分隔符。签名承诺的数据是一个意图消息。在 Sui 中,所有的签名都必须承诺一个意图消息,而不是消息本身。

动机

在先前的版本中,Sui 使用了一个特殊的 Signable trait,它将 Rust 结构体名称作为前缀附加到序列化数据上。这不是理想的,因为它具有以下问题:

  • 不紧凑: 前缀 TransactionData:: 比 1 字节大得多。
  • 不友好: 非 Rust 应用程序需要维护一个 Rust 结构体名称的列表。

意图签名标准为被签名的数据提供了一个紧凑的域分隔符,适用于用户签名和权威签名。它具有多个优点,包括:

  • 意图范围被 u8 表示,而不是 Rust 结构标签名称字符串。
  • 除了意图范围之外,还可以承诺其他重要的域分隔符(例如意图版本和应用程序 ID)。
  • 数据本身不再需要实现 Signable trait,只需要实现 Serialize
  • 所有签名都可以采用相同的意图消息结构,包括用户签名(仅用于承诺 TransactionData)和权威签名(承诺所有内部意图范围,如 TransactionEffectsProofOfPossessionSenderSignedTransaction)。

结构体

IntentMessage 结构体由意图和序列化的数据值组成。

pub struct IntentMessage<T> {
pub intent: Intent,
pub value: T,
}

要创建一个意图结构体,请包括 IntentScope(消息类型的标识)、IntentVersion(网络支持的版本)和 AppId(签名所涉及的应用程序)。

pub struct Intent {
scope: IntentScope,
version: IntentVersion,
app_id: AppId,
}

要查看每个字段的详细定义,请参阅源代码中的每个枚举定义

Intent 的序列化是一个包含每个字段一个字节的 3 字节数组。

IntentMessage<T> 的序列化是意图的 3 字节与 BCS 序列化的消息拼接而成。

用户签名

要创建用户签名,首先构建一个意图消息,然后在交易数据的意图消息的 BCS 序列化值的 32 字节 Blake2b 哈希上创建签名(intent || message)。

以下是一个 Rust 示例:

let intent = Intent::default();
let intent_msg = IntentMessage::new(intent, data);
let signature = Signature::new_secure(&intent_msg, signer);

这是一个 TypeScript 的示例:

const intentMessage = messageWithIntent(
IntentScope.TransactionData,
transactionBytes,
);
const signature = await this.signData(intentMessage);

在底层,Rust 中的 new_secure 方法和 TypeScript 中的 signData 方法执行以下操作:

  1. 将意图消息序列化为包含 3 字节意图和交易数据的 BCS 序列化字节的连接。
  2. 应用 Blake2b 哈希以获取 32 字节摘要。
  3. 将摘要传递给签名 API,对应于签名者的每个支持的方案。支持的签名方案有纯 Ed25519、ECDSA Secp256k1 和 ECDSA Secp256r1。请查看Sui签名以获取每种方案的要求。

权威签名

使用协议密钥创建权威签名。它所提交的数据也是一个意图消息 intent || message。请在源代码中查看所有可用的意图范围。

如何为权威生成拥有证明

当权威请求加入网络时,需要提交协议公钥及其拥有证明(PoP)。PoP 是为了防止恶意密钥攻击

拥有证明是使用权威的协议私钥创建的 BLS 签名,提交的消息是:intent || pubkey || address || epoch。这里 intent 被序列化为 [5, 0, 0],表示意图的范围为“拥有证明”,版本为“V0”和 app_id 为“Sui”。pubkey 是权威的 BLS 协议密钥的序列化公钥字节。address 是与权威帐户密钥关联的帐户地址。epoch 被序列化为 [0, 0, 0, 0, 0, 0, 0, 0]

要在 Rust 中生成拥有证明,请参见 fn generate_proof_of_possession 的实现。有关测试向量,请参见 fn test_proof_of_possession

实现

  1. Struct and enum definitions
  2. Test
  3. User transaction intent signing PR 1, PR 2
  4. Authority intent signing PR 1, PR 2