Skip to main content

Nethereum.ZkProofs

NuGet: Nethereum.ZkProofs | Source: src/Nethereum.ZkProofs/ Provider-agnostic interfaces and models for zero-knowledge proof generation and verification in .NET. This package defines the core abstractions that all Nethereum ZK proof providers implement.

Installation​

dotnet add package Nethereum.ZkProofs

Core Interfaces​

IZkProofProvider​

The central abstraction for proof generation. All providers (browser-based, native, HTTP) implement this interface:

IZkProofProvider provider = ...; // SnarkjsBlazorProvider, RapidSnarkProofProvider, HttpZkProofProvider

var result = await provider.FullProveAsync(new ZkProofRequest
{
CircuitWasm = wasmBytes,
CircuitZkey = zkeyBytes,
InputJson = "{\"nullifier\": \"12345\", \"secret\": \"67890\"}"
});

Console.WriteLine($"Proof: {result.ProofJson}");
Console.WriteLine($"Public signals: {string.Join(", ", result.PublicSignals)}");

ICircuitArtifactSource​

Abstracts how circuit artifacts (WASM binaries, proving keys) are loaded:

// From filesystem
ICircuitArtifactSource source = new FileCircuitArtifactSource("./circuits");
byte[] wasm = await source.GetWasmAsync("commitment");
byte[] zkey = await source.GetZkeyAsync("commitment");

// From memory (pre-loaded bytes)
ICircuitArtifactSource embedded = new EmbeddedCircuitArtifactSource(wasmBytes, zkeyBytes);

// From embedded resources (e.g., Nethereum.PrivacyPools.Circuits)
var privacyPools = new PrivacyPoolCircuitSource();
byte[] wasm = await privacyPools.GetWasmAsync("commitment");

ICircuitGraphSource​

For native witness generation, circuits can be compiled to a graph format (.graph.bin) instead of WASM:

ICircuitGraphSource graphSource = ...;
if (graphSource.HasGraph("commitment"))
{
byte[] graphData = graphSource.GetGraphData("commitment");
// Pass to WitnessCalculator.CalculateWitness(graphData, inputJson)
}

Models​

ZkProofRequest​

Input model for proof generation:

PropertyTypeDescription
CircuitWasmbyte[]WebAssembly circuit binary
CircuitZkeybyte[]Proving key (zkey) binary
InputJsonstringJSON-serialized circuit inputs
WitnessBytesbyte[]Pre-computed witness (.wtns) for native providers
CircuitGraphbyte[]Circuit graph data for native witness generation
CircuitNamestringCircuit identifier
SchemeZkProofSchemeProof scheme (default: Groth16)

ZkProofResult​

Output model with parsed proof data:

ZkProofResult result = await provider.FullProveAsync(request);

// JSON representations
string proofJson = result.ProofJson; // {"pi_a": [...], "pi_b": [...], "pi_c": [...]}
string signalsJson = result.PublicSignalsJson; // ["12345", "67890", ...]

// Parsed public signals as BigInteger[]
BigInteger commitmentHash = result.PublicSignals[0];
BigInteger nullifierHash = result.PublicSignals[1];

Factory method for creating results from JSON:

var result = ZkProofResult.BuildFromJson(ZkProofScheme.Groth16, proofJson, publicSignalsJson);

ZkProofScheme​

public enum ZkProofScheme
{
Unknown = 0,
Groth16 = 1,
Plonk = 2,
Fflonk = 3,
Stark = 4
}

Providers​

Built-in: HttpZkProofProvider​

Delegates proof generation to a remote HTTP endpoint:

var httpClient = new HttpClient();
var provider = new HttpZkProofProvider(httpClient, "https://prover.example.com/prove");

var result = await provider.FullProveAsync(new ZkProofRequest
{
CircuitWasm = wasmBytes,
CircuitZkey = zkeyBytes,
InputJson = inputJson
});

External Providers​

PackageProviderPlatformDescription
Nethereum.ZkProofs.Snarkjs.BlazorSnarkjsBlazorProviderBrowser (Blazor WASM)JS interop with snarkjs
Nethereum.ZkProofs.RapidSnarkRapidSnarkProofProviderDesktop/ServerNative C++ via P/Invoke
Nethereum.ZkProofsVerifierN/A (verification only)All platformsPure C# BN128 Groth16 verifier

Groth16 Utilities​

Convert proof JSON to Solidity-compatible format for on-chain verification:

using Nethereum.ZkProofs.Groth16;

var proof = Groth16ProofConverter.ParseProofJson(result.ProofJson);
var (pA, pB, pC) = Groth16ProofConverter.ToSolidityProof(proof);

// pA, pB, pC are ready for Solidity Groth16Verifier.verifyProof(pA, pB, pC, publicSignals)

Circuit Artifact Locator​

Resolves filesystem paths following the standard circuit directory layout:

var locator = new CircuitArtifactLocator("./circuits");

string wasmPath = locator.GetWasmPath("commitment"); // ./circuits/commitment/commitment.wasm
string zkeyPath = locator.GetZkeyPath("commitment"); // ./circuits/commitment/commitment.zkey
string vkPath = locator.GetVkPath("commitment"); // ./circuits/commitment/commitment_vk.json

if (locator.HasArtifacts("commitment"))
{
// Both WASM and zkey exist
}

Supported Frameworks​

net451, net461, netstandard2.0, net6.0, net8.0, net9.0, net10.0