The main function of interest is located in honk_verifier.cairo
The contract interface will be
#[starknet::interface]
trait IUltraKeccakZKHonkVerifier<TContractState> {
fn verify_ultra_keccak_zk_honk_proof(
self: @TContractState, full_proof_with_hints: Span<felt252>,
) -> Option<Span<u256>>; // Returns the public inputs in case of success.
}
In order to interact with the endpoint, we need to generate the full_proof_with_hintsarray.
To do so, we need a specific proof for your program. But first, Noir requires to specify the inputs of the program in hello/Prover.toml
// The "hello" program simply prove that x!=y, with x being private and y public.
x = "1"
y = "2"
Now, generate a proof with barretenberg, after running the program (notice that the --zkflag that occurs only in the proving part, not in the verifying key generation) :
Using garaga calldatawith the --format array lets you paste this array in cairo code for unit tests by doing let proof:Array<felt252> = [ ... ] ; . The --format starkli has a formatting which is composable with starkli in the command line and also preprends the length of the array so that it can be deserialized by starknet.
Add the Rust Crate to your project using the same release tag as the version of pip package that generated the verifier.
use garaga_rs::calldata::full_proof_with_hints::{
honk::{get_honk_calldata, HonkFlavor, HonkProof, HonkVerificationKey},
zk_honk::{get_zk_honk_calldata, ZKHonkProof},
};
use std::fs::File;
use std::io::Read;
// 1. Add the Rust Crate to your project using the same release tag as the version of pip
// package that generated the verifier.
// 2. Load your verification key
let mut vk_file = File::open("path/to/vk.bin")?;
let mut vk_bytes = vec![];
vk_file.read_to_end(&mut vk_bytes)?;
let vk = HonkVerificationKey::from_bytes(&vk_bytes)?;
// 3. Load the proof and generate the calldata
// For Honk proofs
let mut proof_file = File::open("path/to/proof.bin")?;
let mut proof_bytes = vec![];
proof_file.read_to_end(&mut proof_bytes)?;
let proof = HonkProof::from_bytes(&proof_bytes)?;
let calldata = get_honk_calldata(&proof, &vk, HonkFlavor::KECCAK)?;
// For ZK Honk proofs
let mut zk_proof_file = File::open("path/to/zk_proof.bin")?;
let mut zk_proof_bytes = vec![];
zk_proof_file.read_to_end(&mut zk_proof_bytes)?;
let zk_proof = ZKHonkProof::from_bytes(&zk_proof_bytes)?;
let zk_calldata = get_zk_honk_calldata(&zk_proof, &vk, HonkFlavor::KECCAK)?;
import { getHonkCallData, getZKHonkCallData } from '@garaga/honk';
import { HonkFlavor } from '@garaga/honk/starknet/honkContractGenerator/parsingUtils';
import { readFile } from 'fs/promises';
// 1. Add the NPM package to your project using the same release tag as the version of pip
// package that generated the verifier.
// 2. Load your proof and verification key as Uint8Array
const vk: Uint8Array = await readFile('path/to/vk.bin');
const proof: Uint8Array = await readFile('path/to/proof.bin');
// For Honk proofs (Keccak flavor)
const calldata = getHonkCallData(
proof,
vk,
HonkFlavor.KECCAK // or HonkFlavor.STARKNET for Starknet flavor
);
// For ZK Honk proofs (Keccak flavor)
const zkCalldata = getZKHonkCallData(
proof,
vk,
HonkFlavor.KECCAK // or HonkFlavor.STARKNET for Starknet flavor
);
// The functions return bigint[]
from pathlib import Path
from garaga.definitions import ProofSystem
from garaga.precompiled_circuits.honk import (
HonkVk,
honk_proof_from_bytes
)
from garaga.starknet.honk_contract_generator.calldata import (
get_ultra_flavor_honk_calldata_from_vk_and_proof
)
# 1. Add the pip package to your project using the same release tag as the version that
# generated the verifier.
# 2. Load your proof and verification key
vk_path = Path('path/to/vk.bin')
proof_path = Path('path/to/proof.bin')
# Read the verification key
with open(vk_path, 'rb') as f:
vk_bytes = f.read()
vk = HonkVk.from_bytes(vk_bytes)
# Read and parse the proof
with open(proof_path, 'rb') as f:
proof_bytes = f.read()
# The proof will be parsed according to the system type
# Available proof systems:
# - ProofSystem.UltraKeccakHonk # Regular Honk with Keccak
# - ProofSystem.UltraStarknetHonk # Regular Honk with Starknet hash
# - ProofSystem.UltraKeccakZKHonk # ZK Honk with Keccak
# - ProofSystem.UltraStarknetZKHonk # ZK Honk with Starknet hash
proof = honk_proof_from_bytes(proof_bytes, vk, system=ProofSystem.UltraKeccakHonk)
calldata: list[int] = get_ultra_flavor_honk_calldata_from_vk_and_proof(
vk=vk,
proof=proof, # Can be either HonkProof or ZKHonkProof
system=ProofSystem.UltraKeccakHonk, # Or any other supported system
)
The UltraStarknet Flavour
In order to provide the Ultra Starknet flavour we forked and customized the Barretenberg (bb) implementation. Here the steps to build the customized bb: