#groth16 #zero-knowledge #smart-contracts #zk #near-protocol #cryptography

near_groth16_verifier

Near 协议智能合约的 Groth16 证明验证器实现

2 个稳定版本

1.0.1 2022 年 12 月 1 日

#7#groth16

MIT 许可证

29KB
368

near-groth16-verifier

Rust 库,用于在 NEAR 协议智能合约内部使用验证 Groth16 零知识证明。

用例

在区块链智能合约内部应用零知识密码学已被广泛赞扬为这种新技术最广泛使用的用途之一。在以太坊生态系统中,有许多应用程序使用零知识证明来确保在无许可区块链环境中的数据隐私和计算效率。

使用如 snarky.jscircom 这样的库,开发此类应用程序变得对普通(即非密码学专家)开发者来说更加容易。这些工具通过抽象出所有密码学实现,允许开发者只关注业务逻辑,从而简化了算法的构建。然而,这些工具仅与基于 EVM 的区块链兼容。对于希望在 NEAR 协议上构建基于 zk 的应用程序的开发者来说,这些工具是不够的。

考虑到这一点,我们开发了此库作为使用 groth16 算法 的通用证明验证器。这可以与 snarky.js 和 circom 一起使用,以生成运行 zk 证明的全功能应用程序。

您可以使用此库替换 circom 教程 中的“从智能合约验证”部分。

如何使用它

要在您的智能合约中实现此验证器,您必须首先设置您的逻辑电路并使用 snarky.js 生成一个可信设置。此库将允许您在智能合约内部验证证明是否有效。要这样做,您必须

  1. 通过传递由 snarky.js 生成的设置值来初始化智能合约状态中的验证器
  2. 将验证者二进制文件(由 snarky.js 创建)生成的证明提交给智能合约

验证器可以通过简单的导入实现

use near_sdk::borsh::{self, BorshDeserialize, BorshSerialize};
use near_sdk::json_types::U128;
use near_sdk::{env, near_bindgen, PanicOnDefault, AccountId, BorshStorageKey};
use near_sdk::collections::{LookupSet};
use near_groth16_verifier::{self, Verifier};

#[near_bindgen]
#[derive(PanicOnDefault, BorshDeserialize, BorshSerialize)]
pub struct Contract {
  pub verifier: Verifier,
}

impl Contract {
  #[init]
  pub fn new(
    verifier: Verifier
  ) -> Self {
    assert!(!env::state_exists(), "Already initialized");
    
    Self {
      verifier
    }
  }
}

Verifier 结构可以表示为一系列椭圆曲线点

#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize, Clone, Debug)]
#[serde(crate = "near_sdk::serde")]
pub struct G1Point {
    pub x: U256,
    pub y: U256,
}

#[derive(Serialize, Deserialize, BorshSerialize, BorshDeserialize, Clone)]
#[serde(crate = "near_sdk::serde")]
pub struct G2Point {
    pub x: [U256; 2],
    pub y: [U256; 2],
}

#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize)]
#[serde(crate = "near_sdk::serde")]
pub struct Verifier {
    pub alfa1: G1Point,
    pub beta2: G2Point,
    pub gamma2: G2Point,
    pub delta2: G2Point,
    pub ic: Vec<G1Point>,
    pub snark_scalar_field: U256,
}

要填写这些值,请参阅由 snarky.js 生成的 verification_key.json 文件,它将提供初始化 Verifier 的所有参数,除了 snark_scalar_field

snark_scalar_field 是构建您的电路时使用的标量场的大小。在 snarky.js 中,此变量的标准值是 21888242871839275222246405745257275088548364400416034343698204186575808495617。为了更好地理解此参数,请参阅 circom 文档

初始化验证器后,可以使用它通过 verify 方法评估您的电路中的任何证明,并检查其是否有效。

pub fn verify(&self, input: Vec<U256>, proof: Proof) -> bool

#[derive(Serialize, Deserialize)]
#[serde(crate = "near_sdk::serde")]
pub struct Proof {
    pub a: G1Point,
    pub b: G2Point,
    pub c: G1Point,
}

证明始终遵循相同的结构,并且由 snarky.js 在运行证明算法时生成。

input 参数指的是提供给电路的公输入。这些必须以大整数的 Vec 的形式提供。

Snarky.js 在创建证明时总是生成 2 个文件

  1. public -> 包含应传递给 input 的值的数组
  2. proof -> 包含 json 格式的 Proof 结构

支持的 near-sdk 版本

near-groth16-verifier 是基于 near-sdk 4.0.0 构建的,并将定期更新以反映 near-sdk 的更新。之前的 near-sdk 版本与此库不兼容。

依赖项

~5.5MB
~107K SLoC