零知识证明验证 midnight-proofs:proof-verification

零知识证明验证技能专注于在区块链交易提交前,在服务器端对ZK-SNARKs或ZK-STARKs等零知识证明进行密码学验证。该技能用于构建验证网关、实现批量验证、优化交易成功率,并确保来自不受信任客户端的证明有效性。关键词:零知识证明、ZK验证、区块链安全、密码学验证、交易预验证、批量验证、证明网关、Gas优化。

加密算法 0 次安装 0 次浏览 更新于 2/26/2026

name: midnight-proofs:proof-verification description: 在服务器端验证ZK证明,在交易提交前验证证明,构建验证网关,实现批量验证,或调试证明生成问题。

证明验证

在向网络提交交易之前,在服务器端验证ZK证明,以尽早捕获无效证明并减少失败交易。

何时使用

  • 在向网络提交交易之前验证证明
  • 为传入的证明构建验证网关
  • 为高吞吐量系统实现批量验证
  • 作为API请求的一部分检查证明有效性
  • 调试证明生成问题

关键概念

为什么要在服务器端验证?

好处 描述
快速失败 在网络提交前捕获无效证明
节省Gas 避免为无效证明支付交易费用
更好的用户体验 向用户提供即时反馈
安全性 验证来自不受信任客户端的证明

验证 vs 校验

  • 验证 - 密码学检查,确保证明对电路有效
  • 校验 - 业务逻辑检查(例如,正确的公共输入)
// 同时进行验证和校验
async function verifyAndValidate(proof: Proof, publicInputs: PublicInputs): Promise<boolean> {
  // 步骤1: 密码学验证
  const isValidProof = await verifier.verify(proof, publicInputs);
  if (!isValidProof) return false;

  // 步骤2: 业务校验
  const isValidBusiness = validateBusinessRules(publicInputs);
  return isValidBusiness;
}

验证性能

验证比证明生成快得多:

操作 典型持续时间
证明生成 5-30 秒
证明验证 10-100 毫秒

参考资料

文档 描述
verification-api.md 验证器SDK设置和API参考

示例

示例 描述
pre-submit-validation/ 在交易提交前验证
batch-verification/ 并行验证多个证明

快速开始

1. 设置验证器

import { createVerifier } from '@midnight-ntwrk/midnight-js-verifier';

const verifier = await createVerifier({
  verificationKeysPath: './circuit-keys',
});

2. 验证单个证明

async function verifyProof(
  circuitId: string,
  proof: Uint8Array,
  publicInputs: Record<string, unknown>
): Promise<boolean> {
  try {
    const result = await verifier.verify(circuitId, proof, publicInputs);
    return result.valid;
  } catch (error) {
    console.error('验证失败:', error);
    return false;
  }
}

3. 提交前验证

async function submitWithVerification(
  transaction: Transaction
): Promise<string> {
  // 从交易中提取证明和公共输入
  const { proof, publicInputs, circuitId } = transaction;

  // 先验证
  const isValid = await verifyProof(circuitId, proof, publicInputs);
  if (!isValid) {
    throw new Error('证明验证失败');
  }

  // 提交到网络
  return await submitTransaction(transaction);
}

常见模式

验证网关

import express from 'express';

const app = express();

app.post('/api/verify', async (req, res) => {
  const { circuitId, proof, publicInputs } = req.body;

  try {
    const result = await verifier.verify(
      circuitId,
      Buffer.from(proof, 'base64'),
      publicInputs
    );

    res.json({
      valid: result.valid,
      circuitId,
      verificationTime: result.duration,
    });
  } catch (error) {
    res.status(400).json({
      valid: false,
      error: error.message,
    });
  }
});

批量验证

interface ProofBatch {
  circuitId: string;
  proof: Uint8Array;
  publicInputs: Record<string, unknown>;
}

async function verifyBatch(
  proofs: ProofBatch[]
): Promise<Map<number, boolean>> {
  const results = new Map<number, boolean>();

  // 并行验证
  const verifications = proofs.map(async (p, index) => {
    try {
      const result = await verifier.verify(
        p.circuitId,
        p.proof,
        p.publicInputs
      );
      results.set(index, result.valid);
    } catch {
      results.set(index, false);
    }
  });

  await Promise.all(verifications);
  return results;
}

缓存已验证的证明

import { createHash } from 'crypto';

const verifiedProofs = new Map<string, boolean>();

function proofHash(proof: Uint8Array, publicInputs: Record<string, unknown>): string {
  const data = JSON.stringify({ proof: proof.toString(), publicInputs });
  return createHash('sha256').update(data).digest('hex');
}

async function verifyWithCache(
  circuitId: string,
  proof: Uint8Array,
  publicInputs: Record<string, unknown>
): Promise<boolean> {
  const hash = proofHash(proof, publicInputs);

  // 检查缓存
  if (verifiedProofs.has(hash)) {
    return verifiedProofs.get(hash)!;
  }

  // 验证
  const result = await verifier.verify(circuitId, proof, publicInputs);
  verifiedProofs.set(hash, result.valid);

  return result.valid;
}

带超时的验证

async function verifyWithTimeout(
  circuitId: string,
  proof: Uint8Array,
  publicInputs: Record<string, unknown>,
  timeoutMs = 5000
): Promise<boolean> {
  const controller = new AbortController();
  const timeout = setTimeout(() => controller.abort(), timeoutMs);

  try {
    const result = await verifier.verify(circuitId, proof, publicInputs, {
      signal: controller.signal,
    });
    return result.valid;
  } catch (error) {
    if (error.name === 'AbortError') {
      throw new Error('验证超时');
    }
    throw error;
  } finally {
    clearTimeout(timeout);
  }
}

错误分类

enum VerificationError {
  INVALID_PROOF = 'INVALID_PROOF',
  INVALID_PUBLIC_INPUTS = 'INVALID_PUBLIC_INPUTS',
  CIRCUIT_NOT_FOUND = 'CIRCUIT_NOT_FOUND',
  MALFORMED_PROOF = 'MALFORMED_PROOF',
  TIMEOUT = 'TIMEOUT',
}

function classifyVerificationError(error: Error): VerificationError {
  if (error.message.includes('circuit')) {
    return VerificationError.CIRCUIT_NOT_FOUND;
  }
  if (error.message.includes('public input')) {
    return VerificationError.INVALID_PUBLIC_INPUTS;
  }
  if (error.message.includes('malformed')) {
    return VerificationError.MALFORMED_PROOF;
  }
  if (error.message.includes('timeout')) {
    return VerificationError.TIMEOUT;
  }
  return VerificationError.INVALID_PROOF;
}

性能考虑

关注点 缓解措施
验证密钥加载 在启动时预加载密钥
高请求量 使用验证缓存
大批量 限制并发验证数量
内存使用 流式处理大型证明批次

相关技能

  • proof-generation - 在服务器端生成证明
  • proof-caching - 缓存验证结果
  • prover-optimization - 优化创建证明的证明器

相关命令

当前未定义。