Skip to content

Commit cb7c8ab

Browse files
authored
Supports the native halo2 verifier (#81)
To reduce gas consumption, we introduce another verification method based on the native Halo2 verifier. Compared to the previous BN254 algebra move method, the new method offers significantly higher performance.
1 parent 9ba13dc commit cb7c8ab

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+2681
-1994
lines changed

.github/workflows/ci.yml

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ jobs:
2525
uses: Swatinem/rust-cache@v2
2626
with:
2727
workspaces: |
28-
crates/verifier-sdk
28+
crates/aptos-verifier-api
2929
crates/vk-gen-examples
30+
crates/halo2
31+
crates/halo2-verifier
3032
3133
- name: Cache Aptos CLI
3234
id: cache-aptos
@@ -66,22 +68,27 @@ jobs:
6668

6769
- name: Code formatting check
6870
run: |
69-
cargo fmt --manifest-path ./crates/verifier-sdk/Cargo.toml -- --check
71+
cargo fmt --manifest-path ./crates/aptos-verifier-api/Cargo.toml -- --check
7072
cargo fmt --manifest-path ./crates/vk-gen-examples/Cargo.toml -- --check
73+
cargo fmt --manifest-path ./crates/halo2/Cargo.toml -- --check
74+
cargo fmt --manifest-path ./crates/halo2-verifier/Cargo.toml -- --check
7175
7276
- name: Clippy lint
7377
run: |
74-
cargo clippy --manifest-path ./crates/verifier-sdk/Cargo.toml --all-targets --all-features -- -D warnings
78+
cargo clippy --manifest-path ./crates/aptos-verifier-api/Cargo.toml --all-targets --all-features -- -D warnings
7579
cargo clippy --manifest-path ./crates/vk-gen-examples/Cargo.toml --all-targets --all-features -- -D warnings
76-
80+
cargo clippy --manifest-path ./crates/halo2/Cargo.toml --all-targets --all-features -- -D warnings
81+
cargo clippy --manifest-path ./crates/halo2-verifier/Cargo.toml --all-targets --all-features -- -D warnings
7782
7883
- name: Run Move tests
7984
run: |
80-
aptos move test --package-dir ./packages/common --skip-fetch-latest-git-deps --dev --experiments spec-check=off
81-
aptos move test --package-dir ./packages/verifier --skip-fetch-latest-git-deps --dev --experiments spec-check=off
82-
aptos move test --package-dir ./packages/api --skip-fetch-latest-git-deps --dev --experiments spec-check=off
85+
# aptos move test --package-dir ./packages/common --skip-fetch-latest-git-deps --dev --experiments spec-check=off
86+
# aptos move test --package-dir ./packages/verifier --skip-fetch-latest-git-deps --dev --experiments spec-check=off
87+
# aptos move test --package-dir ./packages/api --skip-fetch-latest-git-deps --dev --experiments spec-check=off
8388

8489
- name: Run Rust tests
8590
run: |
86-
cargo test --manifest-path ./crates/verifier-sdk/Cargo.toml --all-features
87-
cargo test --manifest-path ./crates/vk-gen-examples/Cargo.toml --all-features
91+
cargo test --manifest-path ./crates/aptos-verifier-api/Cargo.toml --all-features
92+
cargo test --manifest-path ./crates/vk-gen-examples/Cargo.toml --all-features
93+
cargo test --manifest-path ./crates/halo2/Cargo.toml --all-features
94+
cargo test --manifest-path ./crates/halo2-verifier/Cargo.toml --all-features

.vscode/settings.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"rust-analyzer.linkedProjects": [
33
"./crates/verifier-sdk/Cargo.toml",
4-
"./crates/vk-gen-examples/Cargo.toml",
4+
"./crates/vk-gen-examples/Cargo.toml",
55
]
66
}
Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
[workspace]
22
members = [
3-
"shape-generator",
4-
# "aptos-verifier-api"
3+
"halo2-verifier",
4+
"aptos-verifier-api",
5+
"halo2",
6+
"vk-gen-examples",
57
]
68
resolver = "2"
79

@@ -13,6 +15,17 @@ categories = ["cryptography"]
1315
edition = "2021"
1416

1517
[workspace.dependencies]
18+
halo2-verifier={path="./halo2-verifier"}
19+
aptos-verifier-api={path="./aptos-verifier-api"}
20+
halo2={path="./halo2"}
21+
vk-gen-examples={path="./vk-gen-examples"}
22+
23+
halo2_proofs = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove", default-features = false, features = ["batch", "bits"] }
24+
halo2_frontend = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove", default-features = false, features = ["bits"] }
25+
halo2_middleware = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove" }
26+
halo2_backend = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove" }
27+
halo2curves = { git = "https://github.com/zkmove/halo2curves", branch = "zkmove" }
28+
1629
ff = { version = "0.13.0" }
1730
num-traits = { version = "0.2.17" }
1831
derivative = { version = "2.2.0" }
@@ -21,13 +34,7 @@ rand_core = { version = "0.6" }
2134
serde = { version = "1" }
2235
serde_json = { version = "1" }
2336
hex = { version = "0.4.3" }
24-
halo2_proofs = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove", default-features = false, features = ["batch", "bits"] }
25-
halo2_frontend = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove", default-features = false, features = ["bits"] }
26-
halo2_middleware = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove" }
27-
halo2_backend = { git = "https://github.com/zkmove/halo2.git", branch = "zkmove" }
28-
halo2curves = { git = "https://github.com/zkmove/halo2curves", branch = "zkmove" }
37+
hex-literal = { version = "0.4.1" }
2938
bcs = { version = "0.1.6" }
3039
blake2b_simd = { version = "1" }
3140
anyhow = { version = "1.0.38" }
32-
33-
shape-generator={path="./shape-generator"}

crates/verifier-sdk/aptos-verifier-api/Cargo.toml renamed to crates/aptos-verifier-api/Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ edition.workspace = true
99
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1010

1111
[dependencies]
12-
shape-generator.workspace=true
12+
halo2-verifier.workspace=true
1313
serde.workspace=true
1414
serde_json.workspace=true
1515
halo2_proofs.workspace=true
16+
halo2_backend.workspace=true
1617
hex.workspace=true
18+
rand.workspace = true
1719
rand_core.workspace=true
1820
anyhow.workspace=true
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
use crate::types::{ArgWithTypeJSON, EntryFunctionArgumentsJSON, HexEncodedBytes};
2+
use anyhow::{Error, Result};
3+
use halo2_backend::arithmetic::CurveAffine;
4+
use halo2_backend::helpers::SerdeFormat;
5+
use halo2_backend::plonk::VerifyingKey;
6+
use halo2_backend::poly::commitment::Params;
7+
use halo2_proofs::halo2curves::bn256::{Bn256, Fr, G1Affine};
8+
use halo2_proofs::halo2curves::ff::{FromUniformBytes, PrimeField};
9+
use halo2_proofs::plonk::Circuit;
10+
use halo2_proofs::poly::kzg::commitment::ParamsKZG;
11+
use halo2_verifier::circuit::{generate_serialized_circuit, generate_serialized_protocol};
12+
use halo2_verifier::params::serialize_kzg_params;
13+
use serde_json::json;
14+
15+
pub mod types;
16+
17+
/// module names shared by move verifier and native verifier
18+
const VERIFIER_MODULE: &str = "verifier_api";
19+
const PARAMS_MODULE: &str = "param_store";
20+
const VK_MODULE: &str = "vk_store";
21+
22+
/// function names for move verifier
23+
const PUBLISH_PROTOCOL_FUNC: &str = "publish_protocol";
24+
const VERIFY_PROOF_FUNC: &str = "verify_proof";
25+
26+
/// function names for native verifier
27+
const PUBLISH_PARAMS_FUNC: &str = "publish_serialized_params";
28+
const PUBLISH_VK_FUNC: &str = "publish_serialized_vk";
29+
const PUBLISH_CIRCUIT_FUNC: &str = "publish_serialized_circuit";
30+
31+
/// Move verifier related APIs
32+
/// build publish protocol transaction payload for aptos.
33+
/// Returns a structure which can be serialized to json string,
34+
/// and when output the json to file, it can be run by `aptos move run`.
35+
pub fn build_publish_protocol_transaction_payload<ConcreteCircuit>(
36+
params: &ParamsKZG<Bn256>,
37+
circuit: &ConcreteCircuit,
38+
verifier_address: String,
39+
) -> Result<EntryFunctionArgumentsJSON, Error>
40+
where
41+
ConcreteCircuit: Circuit<Fr>,
42+
{
43+
let protocol = generate_serialized_protocol(params, circuit)
44+
.expect("generate circuit info should not fail");
45+
46+
let args: Vec<_> = protocol
47+
.into_iter()
48+
.map(|arg| ArgWithTypeJSON {
49+
arg_type: "hex".to_string(),
50+
value: json!(arg
51+
.into_iter()
52+
.map(|i| HexEncodedBytes(i).to_string())
53+
.collect::<Vec<_>>()),
54+
})
55+
.collect();
56+
let json = EntryFunctionArgumentsJSON {
57+
function_id: format!(
58+
"{}::{}::{}",
59+
verifier_address, VERIFIER_MODULE, PUBLISH_PROTOCOL_FUNC
60+
),
61+
type_args: vec![],
62+
args,
63+
};
64+
Ok(json)
65+
}
66+
67+
/// Move verifier related APIs
68+
/// Build verify proof transaction payload for aptos.
69+
/// Returns a structure which can be serialized to json string,
70+
/// and when output the json to file, it can be run by `aptos move run`.
71+
#[allow(clippy::let_and_return)]
72+
pub fn build_verify_proof_transaction_payload(
73+
proof: Vec<u8>,
74+
proof_kzg_variant: u8,
75+
instances: Vec<Vec<Fr>>,
76+
verifier_address: String,
77+
param_address: String,
78+
protocol_address: String,
79+
) -> EntryFunctionArgumentsJSON {
80+
let instances = instances
81+
.iter()
82+
.map(|fr| {
83+
fr.iter()
84+
.map(|f| HexEncodedBytes(f.to_repr().as_ref().to_vec()).to_string())
85+
.collect::<Vec<_>>()
86+
})
87+
.collect::<Vec<_>>();
88+
let json = EntryFunctionArgumentsJSON {
89+
function_id: format!(
90+
"{}::{}::{}",
91+
verifier_address, VERIFIER_MODULE, VERIFY_PROOF_FUNC
92+
),
93+
type_args: vec![],
94+
args: vec![
95+
ArgWithTypeJSON {
96+
arg_type: "address".to_string(),
97+
value: json!(param_address),
98+
},
99+
ArgWithTypeJSON {
100+
arg_type: "address".to_string(),
101+
value: json!(protocol_address),
102+
},
103+
ArgWithTypeJSON {
104+
arg_type: "hex".to_string(),
105+
value: json!(instances),
106+
},
107+
ArgWithTypeJSON {
108+
arg_type: "hex".to_string(),
109+
value: json!(HexEncodedBytes(proof.clone()).to_string()),
110+
},
111+
ArgWithTypeJSON {
112+
arg_type: "u8".to_string(),
113+
value: json!(proof_kzg_variant),
114+
},
115+
],
116+
};
117+
118+
json
119+
}
120+
121+
/// Native verifier related APIs
122+
/// Build publish serialized kzg params transaction payload for aptos.
123+
pub fn build_publish_params_transaction_payload(
124+
params: &ParamsKZG<Bn256>,
125+
params_store_address: String,
126+
) -> Result<EntryFunctionArgumentsJSON, Error> {
127+
let params_bytes = serialize_kzg_params(&params.verifier_params())
128+
.map_err(|e| Error::msg(format!("serialize kzg params failed: {}", e)))?;
129+
let json = EntryFunctionArgumentsJSON {
130+
function_id: format!(
131+
"{}::{}::{}",
132+
params_store_address, PARAMS_MODULE, PUBLISH_PARAMS_FUNC
133+
),
134+
type_args: vec![],
135+
args: vec![ArgWithTypeJSON {
136+
arg_type: "hex".to_string(),
137+
value: json!(HexEncodedBytes(params_bytes).to_string()),
138+
}],
139+
};
140+
Ok(json)
141+
}
142+
143+
/// Native verifier related APIs
144+
/// Build publish serialized vk transaction payload for aptos.
145+
pub fn build_publish_vk_transaction_payload(
146+
vk: &VerifyingKey<G1Affine>,
147+
vk_store_address: String,
148+
) -> EntryFunctionArgumentsJSON {
149+
let vk_bytes = vk.to_bytes(SerdeFormat::RawBytes);
150+
let json = EntryFunctionArgumentsJSON {
151+
function_id: format!("{}::{}::{}", vk_store_address, VK_MODULE, PUBLISH_VK_FUNC),
152+
type_args: vec![],
153+
args: vec![ArgWithTypeJSON {
154+
arg_type: "hex".to_string(),
155+
value: json!(HexEncodedBytes(vk_bytes).to_string()),
156+
}],
157+
};
158+
json
159+
}
160+
161+
/// Native verifier related APIs
162+
/// Build publish serialized circuit transaction payload for aptos.
163+
pub fn build_publish_circuit_transaction_payload<C, P, ConcreteCircuit>(
164+
params: &P,
165+
circuit: &ConcreteCircuit,
166+
vk_store_address: String,
167+
) -> Result<EntryFunctionArgumentsJSON, Error>
168+
where
169+
C: CurveAffine,
170+
P: Params<C>,
171+
ConcreteCircuit: Circuit<C::Scalar>,
172+
C::Scalar: FromUniformBytes<64>,
173+
C::ScalarExt: FromUniformBytes<64>,
174+
{
175+
let circuit_bytes = generate_serialized_circuit(params, circuit)
176+
.map_err(|e| Error::msg(format!("generate serialized circuit failed: {}", e)))?;
177+
178+
let json = EntryFunctionArgumentsJSON {
179+
function_id: format!(
180+
"{}::{}::{}",
181+
vk_store_address, VK_MODULE, PUBLISH_CIRCUIT_FUNC
182+
),
183+
type_args: vec![],
184+
args: vec![ArgWithTypeJSON {
185+
arg_type: "hex".to_string(),
186+
value: json!(HexEncodedBytes(circuit_bytes).to_string()),
187+
}],
188+
};
189+
Ok(json)
190+
}
File renamed without changes.

crates/verifier-sdk/shape-generator/Cargo.toml renamed to crates/halo2-verifier/Cargo.toml

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[package]
2-
name = "shape-generator"
2+
name = "halo2-verifier"
33
version.workspace = true
44
edition.workspace = true
55

@@ -13,11 +13,16 @@ halo2_middleware.workspace=true
1313
bcs.workspace=true
1414
blake2b_simd.workspace=true
1515
halo2curves.workspace=true
16+
hex.workspace=true
17+
hex-literal.workspace=true
18+
rand.workspace = true
19+
halo2.workspace = true
20+
vk-gen-examples.workspace = true
1621

1722
ark-bn254 = "0.4.0"
1823
ark-ec = "0.4.0"
1924
ark-ff = "0.4.0"
2025
ark-serialize = "0.4.0"
21-
hex = "0.4.3"
2226
group = "0.13"
23-
byteorder = "1.5.0"
27+
byteorder = "1.5.0"
28+
anyhow = "1.0.95"

0 commit comments

Comments
 (0)