NUT-12:离线电子现金签名验证

  • cashubtc
  • 发布于 2025-03-26 16:31
  • 阅读 14

该文档提出了 Cashu 加密系统的一个扩展,允许用户 Alice 仅使用 mint Bob 的公钥来验证 Bob 的签名。同时解释了另一个用户 Carol 如何验证从 Alice 那里收到的 ecash 。通过离散对数等式(DLEQ)证明来实现这一点,该证明用于证明 mint 在创建其公钥 A 和签署 BlindedMessage B' 时使用了相同的私钥 a。

NUT-12: 离线 ecash 签名验证

optional


本文档介绍 Cashu 加密系统的一个扩展,允许用户 Alice 仅使用 Bob 的公钥来验证 mint Bob 的签名。我们解释了另一个从 Alice 收到 ecash 的用户 Carol 如何执行 DLEQ 证明。这是通过离散对数等式 (DLEQ) 证明实现的。以前,Bob 的签名只能由他自己使用他自己的私钥来检查 (NUT-00)。

DLEQ 证明

DLEQ 的目的是证明 mint 使用了相同的私钥 a 来创建其公钥 A (NUT-01) 和签署 BlindedMessage B'Bob 除了盲签名 C' 之外,还返回 DLEQ 证明,用于 mint 或 swap 操作。

完整的 DLEQ 证明如下:

## DLEQ 证明

(以下步骤在 Bob 返回 C' 时发生)

Bob:
r = 随机 nonce
R1 = r*G
R2 = r*B'
e = hash(R1,R2,A,C')
s = r + e*a
return e, s

Alice:
R1 = s*G - e*A
R2 = s*B' - e*C'
e == hash(R1,R2,A,C')

如果为真,则 A = a*G 中的 a 必须等于 C' = a*B' 中的 a

Hash 函数

hash 函数 hash(x: <Array<[PublicKey]>) -> bytes 为给定的 PublicKey 输入列表生成确定性的 SHA256 hash。在进行 SHA256 hash 之前,每个 PublicKey 的未压缩(32+32+1)字节十六进制表示形式(130 个字符)会被连接起来。

def hash_e(*publickeys: PublicKey) -> bytes:
    e_ = ""
    for p in publickeys:
        _p = p.serialize(compressed=False).hex()
        e_ += str(_p)
    e = hashlib.sha256(e_.encode("utf-8")).digest()
    return e

[!NOTE] 有关有效 DLEQ 证明的示例,请参阅测试向量

Mint 到用户:BlindSignature 中的 DLEQ

mint 在返回用于 mint (NUT-04) 和交换 (NUT-03) token 的响应中的 BlindSignature 时,会生成这些 DLEQ 证明。BlindSignature 对象以以下方式扩展,以包含 DLEQ 证明:

{
  "id": <str>,
  "amount": <int>,
  "C_": <str>,
  "dleq": { <-- 新增:DLEQ 证明
    "e": <str>,
    "s": <str>
  }
}

es 是 DLEQ 证明。

用户到用户:Proof 中的 DLEQ

为了使 Alice 能够将 DLEQ 传达给另一个用户 Carol,我们扩展了 Proof(参见 NUT-00)对象并包含 DLEQ 证明。如下所述,我们还需要包含 blinding factor r,以使证明对另一个用户 Carol 具有说服力。

{
  "id": <str>,
  "amount": <int>,
  "secret": <str>,
  "C": <str>,
  "dleq": { <-- 新增:DLEQ 证明
    "e": <str>,
    "s": <str>,
    "r": <str>
  }
}

esBob 返回的 DLEQ 证明的 challenge 和 response,rAlice 用于生成 Proof 的 blinding factor。Alice 像 token 中的任何其他证明一样序列化这些证明(参见 NUT-00)以将其发送给另一个用户 Carol

[!IMPORTANT]

隐私: blinding factor r 不应与 mint 共享,否则 mint 将能够将 BlindSignatureProof 关联起来。

Alice(mint 用户)验证 DLEQ 证明

当 mint 或交换 token 时,Alice 会从 mint BobBlindSignature 响应中收到 DLEQ 证明。Alice 通过以下公式检查她收到的每个 ecash token 的 DLEQ 证明的有效性:

R1 = s*G - e*A
R2 = s*B' - e*C'
e == hash(R1,R2,A,C') # 必须为 True

这里,变量是

  • ABob 用于签署此证明的公钥
  • (e, s)Bob 返回的 DLEQ 证明
  • B'AliceBlindedMessage
  • C'BobB'BlindSignature

为了执行证明,Alice 需要 e, s,它们由 BobBlindSignature 中返回。Alice 还需要 B'Alice 创建并由 Bob 签名的 BlindedMessage)和 C'BlindSignature 响应中的盲签名)来自 Bob,以及 ABob 用来签署 BlindedMessage 的公钥)。所有这些值在调用 mint 和 swap 操作期间或之后对 Alice 可用。

如果 DLEQ 证明包含在 mint 的 BlindSignature 响应中,钱包必须验证 DLEQ 证明。

Carol(另一个用户)验证 DLEQ 证明

Carol 是从另一个用户 Alice 的 token 中收到 Proofs 的用户。当 Alice 将带有 DLEQ 证明的 Proofs 发送给 Carol 或当 Alice 公开发布 Proofs 时,Carol 可以自己验证 DLEQ 证明并验证 Bob 的签名,而无需与 Bob 交谈。AliceProof 中包含以下信息(见上文):

  • (x, C) – ecash Proof
  • (e, s) – 由 Alice 揭示的 DLEQ 证明
  • rAlice 的 blinding factor

这里,x 是 Proof 的 secret,C 是 mint 对它的签名。为了像上面的 Alice 一样执行 DLEQ 证明,Carol 需要 (B', C'),她可以使用从 Alice 收到的 blinding factor r 自己计算它们。

为了验证收到的 token 的 DLEQ 证明,Carol 需要使用 Alice 包含在她发送给 CarolProof 中的 blinding factor r 来重建 B'C'。由于 Carol 现在拥有所有必要的信息,因此她可以执行相同的公式来验证 DLEQ 证明,就像 Alice 所做的那样:

Y = hash_to_curve(x)
C' = C + r*A
B' = Y + r*G

R1 = ... (与 Alice 相同)

如果收到的 token 中包含 DLEQ 证明,钱包必须验证该证明。

Mint 信息设置

NUT-06 MintMethodSetting 指示对此功能的支持:

{
  "12": {
    "supported": true
  }
}
  • 原文链接: github.com/cashubtc/nuts...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
cashubtc
cashubtc
江湖只有他的大名,没有他的介绍。