NUT-XX:STARK证明的计算(Cairo)

clealabs 发布于 2025-09-21 阅读 59

本文介绍了一种新的Cashu ecash代币锁定机制,利用Cairo程序的STARK证明作为花费条件。

基于 STARK 证明的计算 (Cairo)

可选
依赖:NUT-10

本 NUT 描述了使用 Cairo 程序执行的 STARK 证明,该证明基于 NUT-10 的知名 Secret 格式定义了一种花费条件。使用 Cairo STARK 证明,可以将电子现金Token锁定到特定 Cairo 程序的成功执行及给定输出。由于 Cairo 是图灵完备的,这实现了用户自定义的任意花费条件,并且由于 STARK 证明的零知识特性,这些条件即使对铸币厂也可以保持隐私[^1]。

[^1]: 这可以通过引导加载实现,详情参见 GPR21 第 2.2.1 节和 可选功能:引导加载

[!CAUTION] 如果铸币厂不支持此类花费条件,证明可能会被视为普通的任何人可花费的Token。应用程序需要通过检查铸币厂的 info 端点,确保铸币厂支持特定种类的花费条件。

Cairo

NUT-10 Secret kind: Cairo

[!NOTE] 在本节中,我们区分三种“证明”:

  1. Proof 指的是 NUT-00 中定义的输入。
  2. CairoProof 指的是程序执行和输出的声明,以及相应的有效 STARK 计算证明。
  3. STARK 证明指的是使用 [S-two 证明器] 生成的底层证明。

如果某个 ProofProof.secretCairo 类型的 Secret,则程序字节码的哈希值位于 Proof.secret.data 中。该证明必须通过提供包含有效 CairoProof 的见证 Proof.witness 来解锁。

[!NOTE] Cairo 程序本身不由铸币厂存储,必须通过其他方式传递(例如,公开共享、带外传输或根据商定的规范推导)。铸币厂仅在 Secret.data 中存储并验证程序字节码的哈希值。

铸币厂将检查 CairoProof.claim.public_data.public_memory.program 的哈希值与 Proof.secret.data 匹配,并验证 STARK 证明的正确性。

此外,它还会检查 CairoProof.claim.public_data.public_memory.output 的哈希值与 Proof.secret.tags.program_output 中的值匹配。

为了给出一个基本案例的具体示例,要铸造一个锁定Token,我们首先创建一个 Cairo Secret,内容如下:

[
  "Cairo",
  {
    "nonce": "859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f",
    "data": "0x0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7",
    "tags": [
      [
        "program_output",
        "0xa431d77da3757f6f3ba829b9cdc171ea170073d1b06caaaae58bf169e9bfc380"
      ]
    ]
  }
]

这里,Secret.data 是 Cairo 程序字节码的哈希值。我们将此 Secret 序列化为 Proof.secret 中的字符串,并从铸币厂获取一个盲签名,该签名存储在 Proof.C 中(参见 NUT-03)。

拥有有效 CairoProof 的接收者,该证明表明程序的执行结果与 Secret.tags.program_output 中的输出匹配,可以通过在 Proof.witness.cairo_proof 中提供该证明来花费此 Proof

{
  "amount": 1,
  "secret": "[\"Cairo\",{\"nonce\":\"859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f\",\"data\":\"0x0249098aa8b9d2fbec49ff8598feb17b592b986e62319a4fa488a3dc36387157a7\",\"tags\":[[\"program_output\",\"0xa431d77da3757f6f3ba829b9cdc171ea170073d1b06caaaae58bf169e9bfc380\"]]}]",
  "C": "02698c4e2b5f9534cd0687d87513c759790cf829aa5739184a3e3735471fbda904",
  "id": "009a1f293253e41e",
  "witness": "{\"cairo_proof\":{\"claim\":{\"public_data\":{\"public_memory\":{\"program\":[[0,[2147450879,67600385,0,0,0,0,0,0]],[1,[2,0,0,0,0,0,0,0]],[2,[2147581952,285507585,0,0,0,0,0,0]],[3,[4,0,0,0,0,0,0,0]],[4,[2147450879,17268737,0,0,0,0,0,0]],[5,[0,0,0,0,0,0,0,0]]]]}}}..."
}

见证格式

CairoWitness 是一个序列化的 JSON 字符串,格式如下:

{
  "cairo_proof": <字符串>,
  "with_bootloader": <布尔值>,
  "with_pedersen": <布尔值>,
}

其中 cairo_proof 是序列化的 CairoProofwith_pedersen 标志指示证明是否包含 Pedersen 执行轨迹,例如在使用引导加载器时需要。

STARK 证明方案

要花费一个用 Cairo 锁定的Token,花费者需要在花费的 Proof 中包含一个 CairoProof。它代表一个 [Cairo 程序] 的执行和输出的声明,以及使用 S-two Cairo 证明器生成的有效 STARK 计算证明。STARK 证明表明指定的 Cairo 程序已正确执行并产生了预期的输出。

[!CAUTION] 应用程序必须确保铸币厂支持所使用的特定版本的 S-two Cairo 证明器。版本兼容性应通过铸币厂的 info 进行验证。

标签

program_output: <felt_str> 确定程序预期输出的哈希值。

程序输出是一个 Cairo Felt 值(域元素)。它使用 Blake2s 哈希函数进行哈希。

可选功能:引导加载

铸币厂可以选择支持 引导加载器 的使用。这使得证明者可以将所执行程序的字节码保密,因为只有指令的哈希值会暴露给铸币厂。

支持的引导加载器及其版本应在铸币厂 info 中指定。

[!NOTE] 此功能是可选的,因为相同的效果可以在没有额外铸币厂端逻辑的情况下实现(引导加载器毕竟只是一个 Cairo 程序)。对于发送者而言,这只是更方便和通用的方式。

示例用例

素数验证

Token可以锁定,要求证明花费者知道一个素数(这只是一个玩具示例,因为找到素数并非困难之事)。

考虑以下检查素数的 Cairo 程序:

/// 检查一个数是否为素数
///
/// # 参数
///
/// * `n` - 要检查的数
///
/// # 返回值
///
/// * `true` 如果该数是素数
/// * `false` 如果该数不是素数
fn is_prime(n: u32) -> bool {
    if n <= 1 {
        return false;
    }
    if n == 2 {
        return true;
    }
    if n % 2 == 0 {
        return false;
    }
    let mut i = 3;
    let mut is_prime = true;
    loop {
        if i * i > n {
            break;
        }
        if n % i == 0 {
            is_prime = false;
            break;
        }
        i += 2;
    }
    is_prime
}

// 可执行入口点
#[executable]
fn main(input: u32) -> bool {
    is_prime(input)
}

该程序在输入为素数时返回 true,否则返回 false,分别对应输出 [1][0](作为 Felt 值的数组)。

以下 Secret 要求花费者证明他们知道一个数 n,使得 is_prime(n) == true(注意,花费者无需透露 n 本身)。

[
  "Cairo",
  {
    "nonce": "859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f",
    "data": "e8d4a51000d4c8a9f1b2e3c5d7a9b8c6e4f2a1d3c5b7e9f1a3b5c7d9e1f3a5b7",
    "tags": [
      [
        "program_output",
        "0xa431d77da3757f6f3ba829b9cdc171ea170073d1b06caaaae58bf169e9bfc380"
      ]
    ]
  }
]

见证将包含声明以及 STARK 证明,表明计算已正确执行:

{
  "amount": 1000,
  "secret": "[\"Cairo\",{\"nonce\":\"859d4935c4907062a6297cf4e663e2835d90d97ecdd510745d32f6816323a41f\",\"data\":\"e8d4a51000d4c8a9f1b2e3c5d7a9b8c6e4f2a1d3c5b7e9f1a3b5c7d9e1f3a5b7\",\"tags\":[[\"program_output\",\"154809849725474173771833689306955346864791482278938452209165301614543497938\"]]}]",
  "C": "03f1e2d3c4b5a69708192a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f80",
  "id": "009a1f293253e41e",
  "witness": "{\"cairo_proof\":{\"claim\":{\"public_data\":{\"public_memory\":{\"program\":[[0,[2147450879,67600385,0,0,0,0,0,0]],[1,[2,0,0,0,0,0,0,0]],[2,[2147581952,285507585,0,0,0,0,0,0]],[3,[4,0,0,0,0,0,0,0]],[4,[2147450879,17268737,0,0,0,0,0,0]],[5,[0,0,0,0,0,0,0,0]]]]}}}..."
}

铸币厂信息设置

NUT-06MintMethodSetting 表示对本功能的支持、可选功能以及 Cairo 证明器的一些配置信息。

{
  "xx": {
    "supported": true,
    "optional_features": {
      "bootloader": {
        "supported": true,
        "version": "0.14.0",
        "hash": "0xaee9298fc7ffd8f4cbcc277b689cbf3a545379fb09ab90cc0245b7fe15c393a9"
      }
    },
    "cairo_prover_config": {
      "version": "0.1.1"
    }
  }
}
  • 原文链接: github.com/clealabs/nuts...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~

相关文章

0 条评论