Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 6 additions & 24 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,6 @@ jobs:

- name: Cache Rust dependencies
uses: Swatinem/rust-cache@v2
with:
workspaces: |
crates/aptos-verifier-api
crates/vk-gen-examples
crates/halo2
crates/halo2-verifier

- name: Cache Aptos CLI
id: cache-aptos
Expand Down Expand Up @@ -67,28 +61,16 @@ jobs:
run: aptos --version

- name: Code formatting check
run: |
cargo fmt --manifest-path ./crates/aptos-verifier-api/Cargo.toml -- --check
cargo fmt --manifest-path ./crates/vk-gen-examples/Cargo.toml -- --check
cargo fmt --manifest-path ./crates/halo2/Cargo.toml -- --check
cargo fmt --manifest-path ./crates/halo2-verifier/Cargo.toml -- --check
run: cargo fmt --all -- --check

- name: Clippy lint
run: |
cargo clippy --manifest-path ./crates/aptos-verifier-api/Cargo.toml --all-targets --all-features -- -D warnings
cargo clippy --manifest-path ./crates/vk-gen-examples/Cargo.toml --all-targets --all-features -- -D warnings
cargo clippy --manifest-path ./crates/halo2/Cargo.toml --all-targets --all-features -- -D warnings
cargo clippy --manifest-path ./crates/halo2-verifier/Cargo.toml --all-targets --all-features -- -D warnings
run: cargo clippy --workspace --all-targets --all-features -- -D warnings

- name: Run Move tests
run: |
# aptos move test --package-dir ./packages/common --skip-fetch-latest-git-deps --dev --experiments spec-check=off
# aptos move test --package-dir ./packages/verifier --skip-fetch-latest-git-deps --dev --experiments spec-check=off
# aptos move test --package-dir ./packages/api --skip-fetch-latest-git-deps --dev --experiments spec-check=off
# aptos move test --package-dir ./packages/common --skip-fetch-latest-git-deps --dev --experiments spec-check=off
# aptos move test --package-dir ./packages/verifier --skip-fetch-latest-git-deps --dev --experiments spec-check=off
# aptos move test --package-dir ./packages/api --skip-fetch-latest-git-deps --dev --experiments spec-check=off

- name: Run Rust tests
run: |
cargo test --manifest-path ./crates/aptos-verifier-api/Cargo.toml --all-features
cargo test --manifest-path ./crates/vk-gen-examples/Cargo.toml --all-features
cargo test --manifest-path ./crates/halo2/Cargo.toml --all-features
cargo test --manifest-path ./crates/halo2-verifier/Cargo.toml --all-features
run: cargo test --workspace --all-features
16 changes: 8 additions & 8 deletions crates/Cargo.toml → Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
[workspace]
members = [
"halo2-verifier",
"aptos-verifier-api",
"halo2",
"vk-gen-examples",
"crates/halo2-verifier",
"crates/aptos-verifier-api",
"crates/halo2",
"crates/vk-gen-examples",
]
resolver = "2"

Expand All @@ -15,10 +15,10 @@ categories = ["cryptography"]
edition = "2021"

[workspace.dependencies]
halo2-verifier={path="./halo2-verifier"}
aptos-verifier-api={path="./aptos-verifier-api"}
halo2={path="./halo2"}
vk-gen-examples={path="./vk-gen-examples"}
halo2-verifier={path="crates/halo2-verifier"}
aptos-verifier-api={path="crates/aptos-verifier-api"}
halo2={path="crates/halo2"}
vk-gen-examples={path="crates/vk-gen-examples"}

halo2_proofs = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove", default-features = false, features = ["batch", "bits"] }
halo2_frontend = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove", default-features = false, features = ["bits"] }
Expand Down
106 changes: 106 additions & 0 deletions packages/api/sources/fast_verifier.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
module verifier_api::fast_verifier {
use std::error;
use std::option::Option;
use std::signer;
use std::vector;
use std::bcs;
use std::proofs::verify_proof;

use verifier_api::param_store::get_serialized_params;

const E_NOT_FOUND: u64 = 1;
const E_EMPTY_VK: u64 = 2;
const E_EMPTY_CIRCUIT: u64 = 3;
const E_VERIFY_PROOF: u64 = 4;


/// Struct to hold serialized verification key
struct SerializedVK has key {
vk_bytes: vector<u8>,
}

/// Struct to hold serialized circuit information, used by the native verifier
struct SerializedCircuit has key {
circuit_bytes: vector<u8>,
}

/// Publishes or updates the serialized verification key for the signer's address
public entry fun publish_serialized_vk(
owner: &signer,
vk_bytes: vector<u8>,
) {
assert!(!vector::is_empty(&vk_bytes), error::invalid_argument(E_EMPTY_VK));

let addr = signer::address_of(owner);

if (exists<SerializedVK>(addr)) {
let res = borrow_global_mut<SerializedVK>(addr);
res.vk_bytes = vk_bytes;
} else {
move_to(owner, SerializedVK { vk_bytes });
}
}

/// Retrieves the serialized verification key for a given address
public fun get_serialized_vk(addr: address): vector<u8> acquires SerializedVK {
assert!(exists<SerializedVK>(addr), error::not_found(E_NOT_FOUND));
*&borrow_global<SerializedVK>(addr).vk_bytes
}

/// Publishes or updates the serialized circuit information for the signer's address
public entry fun publish_serialized_circuit(
owner: &signer,
circuit_bytes: vector<u8>,
) {
assert!(!vector::is_empty(&circuit_bytes), error::invalid_argument(E_EMPTY_CIRCUIT));
let circuit_info = bcs::to_bytes(&circuit_bytes);

let addr = signer::address_of(owner);

if (exists<SerializedCircuit>(addr)) {
let res = borrow_global_mut<SerializedCircuit>(addr);
res.circuit_bytes = circuit_info;
} else {
move_to(owner, SerializedCircuit { circuit_bytes });
}
}

/// Retrieves the serialized circuit information for a given address
public fun get_serialized_circuit(addr: address): vector<u8> acquires SerializedCircuit {
assert!(exists<SerializedCircuit>(addr), error::not_found(E_NOT_FOUND));
*&borrow_global<SerializedCircuit>(addr).circuit_bytes
}

/// Verify proof with the native verifier, aborts on failure
/// `param_address`: address where the params are published
/// `vk_address`: address where the verification key is published
/// `public_inputs`: public inputs as vector of bytes
/// `proof`: proof as vector of bytes
/// `kzg_variant`: 0 for gwc, 1 for shplonk
/// `k`: parameter to downsize params, None to use the full params
public entry fun verify(
param_address: address,
vk_address: address,
public_inputs: vector<u8>,
proof: vector<u8>,
kzg_variant: u8,
k: Option<u32>,
) {
let params = get_serialized_params(param_address);
let vk_bytes = get_serialized_vk(vk_address);
let circuit_info = get_serialized_circuit(vk_address);

assert!(verify_proof(params, vk_bytes, circuit_info, public_inputs, proof, kzg_variant, k), error::aborted(E_VERIFY_PROOF));
}

#[test_only]
public fun mock_verify(
_param_address: address,
_vk_address: address,
_instances: vector<vector<vector<u8>>>,
_proof: vector<u8>,
_kzg_variant: u8,
) {
// do nothing
}
}
2 changes: 2 additions & 0 deletions packages/api/sources/param_store.move
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ module verifier_api::param_store {
)
}

/// Publish the serialized params bytes for the signer
public entry fun publish_serialized_params(
owner: &signer,
params_bytes: vector<u8>,
Expand All @@ -72,6 +73,7 @@ module verifier_api::param_store {
}
}

/// Retrieves the serialized params bytes for a given address
public fun get_serialized_params(addr: address): vector<u8> acquires SerializedParams {
assert!(exists<SerializedParams>(addr), error::not_found(E_PARAMS_NOT_FOUND));
*&borrow_global<SerializedParams>(addr).params_bytes
Expand Down
91 changes: 91 additions & 0 deletions packages/api/sources/verifier.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
module verifier_api::verifier {
use std::error;
use aptos_std::bn254_algebra::Fr;

use verifier_api::param_store::get_params;
use halo2_common::public_inputs::PublicInputs;
use halo2_verifier::halo2_verifier::{verify_single, verify_single_proof};
use halo2_verifier::protocol::{Self, Protocol};

const E_VERIFY_PROOF: u64 = 4;

/// Struct to hold circuit information
struct Circuit has key {
protocol: Protocol,
}

/// Publishes the circuit for the signer's address
public entry fun publish_circuit(
sender: &signer,
general_info: vector<vector<u8>>,
advice_queries: vector<vector<u8>>,
instance_queries: vector<vector<u8>>,
fixed_queries: vector<vector<u8>>,
permutation_columns: vector<vector<u8>>,
fields_pool: vector<vector<u8>>,
gates: vector<vector<u8>>,
lookups_input_exprs: vector<vector<u8>>,
lookups_table_exprs: vector<vector<u8>>,
shuffle_input_exprs: vector<vector<u8>>,
shuffle_exprs: vector<vector<u8>>,
) {
let proto = protocol::from_bytes(
general_info, advice_queries, instance_queries, fixed_queries, permutation_columns,
fields_pool, gates, lookups_input_exprs, lookups_table_exprs, shuffle_input_exprs,
shuffle_exprs
);
move_to(sender, Circuit { protocol: proto });
}

/// destory a circuit
public fun destroy(circuit: Circuit) {
let Circuit { protocol: _ } = circuit;
}

/// Verify proof with move verifier, aborts on failure
///
/// `param_address`: address where the params are published
/// `circuit_address`: address where the circuit is published
/// `public_inputs`: public inputs as vector of vector of bytes
/// `proof`: proof as vector of bytes
/// `kzg_variant`: 0 for gwc, 1 for shplonk
public entry fun verify(
param_address: address,
circuit_address: address,
public_inputs: vector<vector<vector<u8>>>,
proof: vector<u8>,
kzg_variant: u8,
) acquires Circuit {
let params = get_params(param_address);
let circuit = borrow_global<Circuit>(circuit_address);
let protocol = &circuit.protocol;
assert!(verify_single(&params, protocol, public_inputs, proof, kzg_variant), error::aborted(E_VERIFY_PROOF));
}

/// Vefify proof with move verifier, different from `verify`,
/// this function is not entry function, takes `PublicInputs` as input
/// and returns `bool` instead of aborting on failure
public fun verify_proof(
param_address: address,
circuit_address: address,
public_inputs: PublicInputs<Fr>,
proof: vector<u8>,
kzg_variant: u8,
): bool acquires Circuit {
let params = get_params(param_address);
let circuit = borrow_global<Circuit>(circuit_address);
let protocol = &circuit.protocol;
verify_single_proof(&params, protocol, public_inputs, proof, kzg_variant)
}

#[test_only]
public fun mock_verify_proof(
_param_address: address,
_circuit_address: address,
_instances: vector<vector<vector<u8>>>,
_proof: vector<u8>,
_kzg_variant: u8,
) {
// do nothing
}
}
Loading