dusk-plonk电路构建核心解析:Composer、Witness与约束系统概念全解

发布时间:2026/8/25 17:37:18
dusk-plonk电路构建核心解析:Composer、Witness与约束系统概念全解 dusk-plonk电路构建核心解析Composer、Witness与约束系统概念全解【免费下载链接】plonkPure Rust implementation of the PLONK ZKProof System done by the Dusk team项目地址: https://gitcode.com/gh_mirrors/plo/plonkdusk-plonk 是 Dusk 团队用纯 Rust 实现的 PLONK 零知识证明ZKProof系统运行在 BLS12-381 曲线之上内置 KZG10 多项式承诺方案。要在这个库里搭电路、写证明绕不开的三大核心概念就是Composer电路构建器、Witness witness 变量和约束系统Constraint System。本文用尽量少的代码带你一次性把这三者的职责和关系讲清楚帮你快速上手 PLONK 电路构建。一张图看懂 dusk-plonk 的核心流程在深入细节之前先记住这条主线出自项目架构约定 CLAUDE.mdCircuit电路定义 → Composer约束系统 Witness 分配 → Compiler编译 → ProverKey / VerifierKey证明/验证密钥 → Proof证明→ Verify验证阶段核心类型职责电路定义Circuittrait声明要证明什么电路构建Composer分配 witness、追加 gate 约束编译Compiler生成 Prover / Verifier证明与验证Proof生成并校验零知识证明所有公开入口都集中在 prelude 模块中见 src/prelude.rs日常只需要use dusk_plonk::prelude::*就能拿到Composer、Witness、Constraint、Compiler等全部主力类型。Composer电路构建的总指挥Composer是整个约束系统的工地现场定义在 src/composer.rs 中。它内部维护了五样东西constraints: VecGate—— 所有已追加的门约束行witnesses: VecBlsScalar—— 所有 witness 的实际取值public_inputs—— 稀疏存储的公共输入行号 → 值perm—— 置换参数permutation用于 PLONK 的连线证明runtime—— 调试运行时输出 CDF 事件初始化为什么第一个 Composer 不是空的调用Composer::initialized()时系统会自动做三件事分配第 0 号 witness 为0、第 1 号 witness 为1见 src/composer.rs 中的ZERO/ONE常量这是 turbo composer 的硬性约定任何电路的 wire 0、wire 1 永远是零和一用断言把0、1这两个常量钉死在电路里防止被恶意 prover 篡改追加两个 dummy gate见append_dummy_gates防止 witness 多项式退化为零多项式、防止置换退化为恒等置换——这是 PLONK 完备性的关键细节。所以一个空电路其实已经有 4 个约束了。之后你再调用composer.constraints()统计大小时要记得把这部分算进去。常用构建 API 速查方法作用append_witness(x)分配一个新的私有 witness返回Witness索引append_public(x)分配 witness 并追加一个 gate将其标记为公共输入append_constant(x)分配 witness 并断言它等于常量 xgate_add(s)/gate_mul(s)追加一行算术 gate 并自动算出输出 witnessassert_equal(a, b)追加 gate 约束 a bassert_equal_constant(a, c, p)约束 a c可选携带公共输入 pcomponent_range_bits::N(a)范围约束证明 a 是一个 N 位数一个典型的加法约束长这样来自示例 examples/circuit.rslet constraint Constraint::new() .left(1) .right(1) .a(a) .b(b) .constant(BlsScalar::from(42)); let result composer.gate_add(constraint);gate_add的内部逻辑是把q_O设为 -1求解c q_L·a q_R·b q_F·d q_C PI把c作为新 witness 追加进电路再追加一行 gate见append_evaluated_output实现。注意源码里的注释特别强调这一行 gate 就是健全性边界——少了它恶意 prover 就能悄悄替换输出值。Witness电路里的变量盒Witness定义在 src/composer/constraint_system/witness.rs。它本身非常简单——只封装了一个索引pub struct Witness { index: usize }可以把它理解为电路中的接线端子你手里拿到的不是数值本身而是一个指向witnesses数组的号码牌。真正的值由 prover 在证明时填入由约束保证它必须正确。两个内置常量值得记住Witness::ZERO索引 0和Witness::ONE索引 1——对应初始化时钉死的 0 和 1Witness的Default值就是ZERO。每个 gate 有 4 根 wire左 a、右 b、输出 c、第四 dwire 属于哪个 gate 由WireData枚举Left(n)/Right(n)/Output(n)/Fourth(n)描述。置换参数perm正是靠追踪这些 wire 的流向来保证上一行的输出接到下一行的输入这一布线正确性。约束系统与 Gate一行多项式评估这是三件套中最数学的一环。核心类型有两个都在 src/composer/constraint_system/constraint.rsConstraint约束的草稿Constraint是一个 12 个系数 4 个 witness 槽位的结构体通过链式方法配置mult(1).left(1).a(x).b(y)等。系数通过Selector枚举寻址常见的外部选择器有Selector符号含义Multiplicationq_M乘积项系数Left/Rightq_L / q_R左、右 wire 系数Outputq_O输出 wire 系数Fourthq_F第四 wireadvice系数Constantq_C常数项PublicInputPI公共输入项剩下的Arithmetic、Range、Logic、GroupAddFixedBase、GroupAddVariableBase是 dusk-plonk 特有的内部选择器用来区分普通算术 gate 与 range/logic/ECC 加速 gate——这也是它相比标准 PLONK 的自定义门优化所在完整规格见 docs/dusk-plonk-specs.pdf。Gate约束的成品Composer::append_gate会把Constraint固化成一个Gate定义在 src/composer/gate.rs。算术 gate 强制执行的等式是q_M·a·b q_L·a q_R·b q_O·c q_F·d q_C PI 0所有 Gate 按行排成一列就是整条电路。每一列 wirea/b/c/d构成一个 witness 多项式配合 KZG10 承诺见 src/commitment_scheme/kzg10/和 FFTsrc/fft/最终被打包成 PLONK 证明。从示例电路串联三大概念回到 examples/circuit.rs 中的TestCircuit它证明了五件事a 2^6、b 2^4、a b 42 cc 为公共输入、a·b d 42、以及一次 JubJub 曲线上的标量乘法。整个circuit方法就是三大概念的完整演练分配 Witnesscomposer.append_witness(self.a)拿到a的端子加约束component_range_bits::6(a)用一组 gate 锁住 a 的位宽gate_addassert_equal完成加法暴露公共输入composer.append_public(self.c)让验证者无需信任 prover 就知道 c 的值。证明与验证只需三行Compiler::compile::TestCircuit(pp, label)生成 prover/verifierprover.prove(mut rng, circuit)产出Proofverifier.verify(proof, public_inputs)收尾。调试与进阶让电路构建更透明CDF 调试器开启debugfeature 后运行时事件witness 分配、约束追加会输出到 CDF 文件路径由CDF_OUTPUT环境变量指定实现位于 src/debugger.rs方便你逐行分析 gate 构成电路压缩Circuit::compress()可以把电路序列化为字节串之后直接编译而无需重跑电路定义适合嵌入式场景正确性测试tests/ 目录按功能拆分了boolean、range、logic、ecc等集成测试是理解每类 gate 行为的最好教材性能参考README 给出的基准是 2^16 约束规模下证明约 7.9 秒、验证约 2.8 毫秒验证时间与电路规模无关跑测试记得加--releasedebug 模式可能慢上百倍。总结三句话记住 dusk-plonk 的电路构建概念一句话定位关键文件Composer电路工地分配变量、追加 gate 的总指挥src/composer.rsWitness变量端子索引即身份0/1 号永远钉死src/composer/constraint_system/witness.rs约束系统每行 gate 是一个多项式等式整体构成电路src/composer/constraint_system/constraint.rs抓住Circuit → Composer → Compiler → Proof这条主线再对照 examples/circuit.rs 动手改一改你就能快速从读懂 dusk-plonk过渡到用 dusk-plonk 写自己的零知识电路。【免费下载链接】plonkPure Rust implementation of the PLONK ZKProof System done by the Dusk team项目地址: https://gitcode.com/gh_mirrors/plo/plonk创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻