Skip to content

nixprotocol/ultrahonk-go

Repository files navigation

ultrahonk-go

Pure-Go implementation of the Aztec UltraHonk proof verification protocol over the BN254 curve. Compatible with proofs generated by Barretenberg.

Features

  • Full UltraHonk proof verification (sumcheck + Shplemini/KZG pairing)
  • Fiat-Shamir transcript generation (Keccak256-based)
  • 8 relation accumulators: arithmetic, permutation, lookup, delta range, elliptic curve, auxiliary, Poseidon2 external/internal
  • Load verification keys from Barretenberg output (bb write_vk binary and JSON formats)
  • Verification key serialization/deserialization
  • Zero external dependencies beyond gnark-crypto and golang.org/x/crypto

Installation

go get github.com/nixprotocol/ultrahonk-go

Requires Go 1.23+.

Usage

package main

import (
    "fmt"
    "os"

    honk "github.com/nixprotocol/ultrahonk-go"
)

func main() {
    // Load verification key from Barretenberg binary output
    vkData, _ := os.ReadFile("path/to/vk")
    vk, err := honk.DeserializeVKFromBarretenberg(vkData)
    if err != nil {
        panic(err)
    }

    // Or from Barretenberg JSON output
    // vkJSON, _ := os.ReadFile("path/to/vk.json")
    // vk, err := honk.DeserializeVKFromJSON(vkJSON)

    // Parse proof bytes (ProofSize * 32 = 14592 bytes)
    proofBytes := []byte{...} // your proof

    // Parse public inputs from hex strings
    inputs, err := honk.ParsePublicInputs([]string{
        "0x2a711793ab8f5e5050f59b872365ad644e115ad50a23796e6bca4edfa98ac4cd",
        "0x0000000000000000000000000000000000000000000000000000000005f5e100",
        // ... more inputs ...
    })
    if err != nil {
        panic(err)
    }

    verified, err := honk.Verify(vk, proofBytes, inputs)
    if err != nil {
        fmt.Printf("verification error: %v\n", err)
        return
    }
    fmt.Printf("proof valid: %v\n", verified)
}

Loading Verification Keys

Three ways to load a VK:

Method Use case
DeserializeVKFromBarretenberg(data) Binary output from bb write_vk (1760 bytes)
DeserializeVKFromJSON(data) JSON output from bb write_vk --output_format json
DeserializeVK(data) Library's own compact binary format (1752 bytes)

You can also construct a VerificationKey struct directly and serialize it with SerializeVK().

API

Function Description
Verify(vk, proofBytes, publicInputs) Verify an UltraHonk proof against a verification key
ParsePublicInputs(hexStrings) Parse hex-encoded public input strings into field elements
LoadProof(proofBytes) Deserialize raw bytes into a structured Proof
DeserializeVKFromBarretenberg(data) Deserialize a VK from Barretenberg's binary format
DeserializeVKFromJSON(data) Deserialize a VK from Barretenberg's JSON format
SerializeVK(vk) Serialize a VerificationKey to the library's binary format
DeserializeVK(data) Deserialize a VK from the library's binary format

Proof Format

Verify expects proof-only bytes (14,592 bytes = 456 field elements x 32 bytes).

Important: bb prove output includes public inputs prepended to the proof. You must strip them before passing to Verify:

bb prove output layout:
[public_inputs (N * 32 bytes)] [proof (14592 bytes)]

where N = vk.PublicInputsSize (from the VK header)

To split them:

vk, _ := honk.DeserializeVKFromBarretenberg(vkData)
bbOutput, _ := os.ReadFile("path/to/proof")

pubInputBytes := int(vk.PublicInputsSize) * 32
proofBytes := bbOutput[pubInputBytes:]
// Public inputs are typically passed separately (e.g., from your application logic).

The proof body contains:

  • Pairing point object (16 field elements)
  • Wire commitments (W1-W4, ZPerm, lookup helpers) as split-limb G1 points
  • Sumcheck univariates (28 rounds x 8 evaluations)
  • Sumcheck evaluations (40 entities)
  • Gemini fold commitments and evaluations
  • Shplonk and KZG quotient commitments

Protocol Constants

Parameter Value
Max proof size log N 28
Number of entities 40
Subrelations 26
Batched relation partial length 8
Curve BN254

Benchmarks

Apple M1 Pro:

BenchmarkVerify            705    1.65 ms/op    78 KB/op    539 allocs/op
BenchmarkLoadProof       99094   12.3 us/op     16 KB/op      1 allocs/op
BenchmarkSerializeVK   1000000    1.0 us/op    1.8 KB/op      1 allocs/op

Compatibility

Compatible with UltraHonk proofs generated by Barretenberg v0.87. The Fiat-Shamir transcript, relation evaluations, and pairing check match the Solidity verifier specification.

License

Apache License 2.0 - see LICENSE and NOTICE.

About

Pure-Go UltraHonk proof verifier for BN254. Verify Noir circuit proofs natively in Go without Barretenberg.

Topics

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages