From e116ad9a2ecf0f625900427812e52f18935728ea Mon Sep 17 00:00:00 2001 From: "Ya-wen, Jeng" Date: Wed, 2 Oct 2024 21:24:16 +0800 Subject: [PATCH 1/2] feat(ffi): add gkr adapter --- .github/workflows/build-and-test.yml | 42 +++++--- Cargo.lock | 138 +++++++++++++++++++++++++-- mopro-ffi/Cargo.toml | 3 + mopro-ffi/src/gkr/mod.rs | 100 +++++++++++++++++++ mopro-ffi/src/lib.rs | 39 +++++++- 5 files changed, 299 insertions(+), 23 deletions(-) create mode 100644 mopro-ffi/src/gkr/mod.rs diff --git a/.github/workflows/build-and-test.yml b/.github/workflows/build-and-test.yml index 6a950e36..7c11a65b 100644 --- a/.github/workflows/build-and-test.yml +++ b/.github/workflows/build-and-test.yml @@ -46,6 +46,18 @@ jobs: override: true - name: Run ffi circom tests run: cd mopro-ffi && cargo test --features circom --no-default-features + test-ffi-gkr: + runs-on: ubuntu-latest + if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name + steps: + - uses: actions/checkout@v4 + - name: Install Rust toolchain + uses: actions-rs/toolchain@v1 + with: + toolchain: stable + override: true + - name: Run ffi gkr tests + run: cd mopro-ffi && cargo test --features gkr --no-default-features test-e2e: runs-on: ubuntu-latest if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name @@ -80,8 +92,8 @@ jobs: id: cache-xcframework uses: actions/cache/save@v4 with: - path: test-e2e/MoproiOSBindings - key: ${{ github.sha }}-xcframework + path: test-e2e/MoproiOSBindings + key: ${{ github.sha }}-xcframework build-ios-app-device: runs-on: macos-latest needs: build-xcframework @@ -96,8 +108,8 @@ jobs: id: cache-restore-xcframework uses: actions/cache/restore@v4 with: - path: test-e2e/MoproiOSBindings - key: ${{ github.sha }}-xcframework + path: test-e2e/MoproiOSBindings + key: ${{ github.sha }}-xcframework - name: Build app for device run: xcodebuild -project ./test-e2e/ios/mopro-test.xcodeproj -scheme mopro-test -destination generic/platform=iOS build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO build-ios-app-simulator: @@ -114,8 +126,8 @@ jobs: id: cache-restore-xcframework uses: actions/cache/restore@v4 with: - path: test-e2e/MoproiOSBindings - key: ${{ github.sha }}-xcframework + path: test-e2e/MoproiOSBindings + key: ${{ github.sha }}-xcframework - name: Build app for device run: xcodebuild -project ./test-e2e/ios/mopro-test.xcodeproj -scheme mopro-test -destination generic/platform=iOS\ Simulator build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO test-ios-app-simulator: @@ -132,8 +144,8 @@ jobs: id: cache-restore-xcframework uses: actions/cache/restore@v4 with: - path: test-e2e/MoproiOSBindings - key: ${{ github.sha }}-xcframework + path: test-e2e/MoproiOSBindings + key: ${{ github.sha }}-xcframework # to list available simulators: xcrun simctl list devices - name: Test app in simulator run: xcodebuild -project ./test-e2e/ios/mopro-test.xcodeproj -scheme mopro-test -destination 'platform=iOS Simulator,name=iPhone 15' test CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO @@ -153,8 +165,8 @@ jobs: id: cache-android-lib uses: actions/cache/save@v4 with: - path: test-e2e/MoproAndroidBindings - key: ${{ github.sha }}-android-lib + path: test-e2e/MoproAndroidBindings + key: ${{ github.sha }}-android-lib build-android-app: runs-on: ubuntu-latest needs: build-android-lib @@ -169,14 +181,14 @@ jobs: id: cache-restore-android-lib uses: actions/cache/restore@v4 with: - path: test-e2e/MoproAndroidBindings - key: ${{ github.sha }}-android-lib + path: test-e2e/MoproAndroidBindings + key: ${{ github.sha }}-android-lib - name: Setup Java uses: actions/setup-java@v3 with: - distribution: 'temurin' - java-version: 17 + distribution: "temurin" + java-version: 17 - name: Setup Android SDK uses: android-actions/setup-android@v2.0.10 - name: Build android app - run: cd test-e2e/android && ./gradlew build \ No newline at end of file + run: cd test-e2e/android && ./gradlew build diff --git a/Cargo.lock b/Cargo.lock index 45af5d6f..49c0086d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -187,7 +187,7 @@ dependencies = [ "ark-std", "derivative", "hashbrown 0.13.2", - "itertools", + "itertools 0.10.5", "num-traits", "rayon", "zeroize", @@ -205,7 +205,7 @@ dependencies = [ "ark-std", "derivative", "digest 0.10.7", - "itertools", + "itertools 0.10.5", "num-bigint", "num-traits", "paste", @@ -823,7 +823,7 @@ dependencies = [ "clap 2.34.0", "criterion-plot", "csv", - "itertools", + "itertools 0.10.5", "lazy_static", "num-traits", "oorandom", @@ -845,7 +845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2673cc8207403546f45f5fd319a974b1e6983ad1a3ee7e6041650013be041876" dependencies = [ "cast", - "itertools", + "itertools 0.10.5", ] [[package]] @@ -1309,6 +1309,15 @@ dependencies = [ "subtle", ] +[[package]] +name = "ff-ext" +version = "0.1.0" +source = "git+https://github.com/han0110/gkr#5ebd4975bea76596b680906d815a3fe0a8dd1416" +dependencies = [ + "ff 0.13.0", + "goldilocks", +] + [[package]] name = "fixed-hash" version = "0.7.0" @@ -1397,6 +1406,38 @@ version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +[[package]] +name = "gkr" +version = "0.1.0" +source = "git+https://github.com/han0110/gkr#5ebd4975bea76596b680906d815a3fe0a8dd1416" +dependencies = [ + "auto_impl", + "ff-ext", + "itertools 0.11.0", + "rand_chacha", + "rand_core", + "rayon", +] + +[[package]] +name = "gkr-keccak256" +version = "0.1.0" +source = "git+https://github.com/vivianjeng/gkr-keccak256.git#a579f811dc4b31c27955f467b58dd3e3fa0df6a2" +dependencies = [ + "bincode", + "ff-ext", + "gkr", + "goldilocks", + "halo2curves 0.6.1", + "itertools 0.11.0", + "rand", + "rand_core", + "rayon", + "serde", + "serde_json", + "tiny-keccak", +] + [[package]] name = "glob" version = "0.3.1" @@ -1414,6 +1455,19 @@ dependencies = [ "scroll", ] +[[package]] +name = "goldilocks" +version = "0.1.0" +source = "git+https://github.com/han0110/goldilocks?branch=feature/qe_op_b#49742413a1d26a637603dcaa3c0610b4c3104986" +dependencies = [ + "ff 0.13.0", + "halo2curves 0.1.0", + "itertools 0.12.1", + "rand_core", + "serde", + "subtle", +] + [[package]] name = "group" version = "0.12.1" @@ -1449,7 +1503,7 @@ source = "git+https://github.com/ElusAegis/halo2-fibonacci-sample.git#4e5f955c93 dependencies = [ "bincode", "halo2_proofs", - "halo2curves", + "halo2curves 0.3.2", "rand", "serde", "thiserror", @@ -1465,7 +1519,7 @@ dependencies = [ "clap 3.2.25", "ethers-core 0.17.0", "halo2_proofs", - "itertools", + "itertools 0.10.5", "lazy_static", "log", "num-bigint", @@ -1484,7 +1538,7 @@ dependencies = [ "blake2b_simd", "ff 0.13.0", "group 0.13.0", - "halo2curves", + "halo2curves 0.3.2", "rand_chacha", "rand_core", "rayon", @@ -1492,6 +1546,26 @@ dependencies = [ "tracing", ] +[[package]] +name = "halo2curves" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b1142bd1059aacde1b477e0c80c142910f1ceae67fc619311d6a17428007ab" +dependencies = [ + "blake2b_simd", + "ff 0.13.0", + "group 0.13.0", + "lazy_static", + "num-bigint", + "num-traits", + "pasta_curves", + "paste", + "rand", + "rand_core", + "static_assertions", + "subtle", +] + [[package]] name = "halo2curves" version = "0.3.2" @@ -1510,6 +1584,28 @@ dependencies = [ "subtle", ] +[[package]] +name = "halo2curves" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db81d01d0bbfec9f624d7590fc6929ee2537a64ec1e080d8f8c9e2d2da291405" +dependencies = [ + "blake2b_simd", + "ff 0.13.0", + "group 0.13.0", + "lazy_static", + "num-bigint", + "num-traits", + "pairing", + "pasta_curves", + "paste", + "rand", + "rand_core", + "rayon", + "static_assertions", + "subtle", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -1687,6 +1783,24 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.11" @@ -1829,6 +1943,7 @@ dependencies = [ "ark-std", "byteorder", "color-eyre", + "gkr-keccak256", "halo2-fibonacci", "num-bigint", "num-traits", @@ -2011,6 +2126,15 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f" +[[package]] +name = "pairing" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" +dependencies = [ + "group 0.13.0", +] + [[package]] name = "parity-scale-codec" version = "3.6.12" diff --git a/mopro-ffi/Cargo.toml b/mopro-ffi/Cargo.toml index 6e1a15aa..9f8c4560 100644 --- a/mopro-ffi/Cargo.toml +++ b/mopro-ffi/Cargo.toml @@ -35,6 +35,7 @@ circom = [ "num-traits", "byteorder", ] +gkr = [] [dependencies] uniffi = { version = "=0.28.0", features = ["cli", "build"] } @@ -51,6 +52,7 @@ num-bigint = { version = "0.4.3", default-features = false, features = [ "rand", ] } + # ZKP generation ark-ec = { version = "=0.4.1", default-features = false, features = [ "parallel", @@ -86,3 +88,4 @@ serde_derive = "1.0" # Halo2 dependencies halo2-fibonacci = { git = "https://github.com/ElusAegis/halo2-fibonacci-sample.git" } +gkr-keccak256 = { git = "https://github.com/vivianjeng/gkr-keccak256.git" } diff --git a/mopro-ffi/src/gkr/mod.rs b/mopro-ffi/src/gkr/mod.rs new file mode 100644 index 00000000..82dc2b26 --- /dev/null +++ b/mopro-ffi/src/gkr/mod.rs @@ -0,0 +1,100 @@ +use std::error::Error; + +type GkrProofResult = (String, Vec); + +pub type GkrProveFn = fn(Vec) -> Result>; + +pub type GkrVerifyFn = fn(Vec, &str, Vec) -> Result>; + +#[macro_export] +macro_rules! gkr_app { + () => { + fn generate_gkr_proof( + in0: String, + in1: Vec, + ) -> Result { + let name = in0; + let proving_fn = get_gkr_proving_circuit(&name).map_err(|e| { + mopro_ffi::MoproError::GkrError(format!("error getting proving circuit: {}", e)) + })?; + proving_fn(in1) + .map(|(output_claims, proof)| mopro_ffi::GkrProofResult { + output_claims, + proof, + }) + .map_err(|e| mopro_ffi::MoproError::GkrError(format!("gkr error: {}", e))) + } + + fn verify_gkr_proof( + in0: String, + in1: Vec, + in2: String, + in3: Vec, + ) -> Result { + let name = in0; + let verifying_fn = get_gkr_verifying_circuit(&name).map_err(|e| { + mopro_ffi::MoproError::GkrError(format!( + "error getting verification circuit: {}", + e + )) + })?; + verifying_fn(in1, &in2, in3).map_err(|e| { + mopro_ffi::MoproError::GkrError(format!("error verifying proof: {}", e)) + }) + } + }; +} + +#[macro_export] +macro_rules! set_gkr_circuits { + ($(($key:expr, $prove_fn:expr, $verify_fn:expr)),+ $(,)?) => { + fn get_gkr_proving_circuit(circuit: &str) -> Result { + match circuit { + $( + $key => Ok($prove_fn), + )+ + _ => Err(mopro_ffi::MoproError::GkrError(format!("Unknown proving key: {}", circuit))) + } + } + + fn get_gkr_verifying_circuit(circuit: &str) -> Result { + match circuit { + $( + $key => Ok($verify_fn), + )+ + _ => Err(mopro_ffi::MoproError::GkrError(format!("Unknown verifying key: {}", circuit))) + } + } + }; +} +#[cfg(test)] +mod test { + use crate as mopro_ffi; + + gkr_app!(); + + set_gkr_circuits! { + ("keccak256", gkr_keccak256::prove, gkr_keccak256::verify), + } + + #[test] + fn test_generate_and_verify_gkr_proof() { + let input: Vec = vec![ + 116, 101, 115, 116, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, + ]; + + if let Ok(proof_result) = generate_gkr_proof("keccak256".to_string(), input.clone()) { + let result = verify_gkr_proof( + "keccak256".to_string(), + input, + proof_result.output_claims, + proof_result.proof, + ); + + assert!(result.is_ok()); + } else { + panic!("Failed to generate the proof!") + } + } +} diff --git a/mopro-ffi/src/lib.rs b/mopro-ffi/src/lib.rs index e1e8e852..04405ef4 100644 --- a/mopro-ffi/src/lib.rs +++ b/mopro-ffi/src/lib.rs @@ -2,6 +2,8 @@ pub mod app_config; #[cfg(feature = "circom")] mod circom; +#[cfg(feature = "gkr")] +mod gkr; #[cfg(feature = "halo2")] mod halo2; @@ -14,6 +16,9 @@ pub use circom::{ #[cfg(feature = "halo2")] pub use halo2::{Halo2ProveFn, Halo2VerifyFn}; +#[cfg(feature = "gkr")] +pub use gkr::{GkrProveFn, GkrVerifyFn}; + #[cfg(not(feature = "circom"))] #[macro_export] macro_rules! circom_app { @@ -67,6 +72,28 @@ macro_rules! halo2_app { }; } +#[cfg(not(feature = "gkr"))] +#[macro_export] +macro_rules! gkr_app { + () => { + fn generate_gkr_proof( + in0: String, + in1: Vec, + ) -> Result { + panic!("Gkr is not enabled in this build. Please pass `gkr` feature to `mopro-ffi` to enable Gkr.") + } + + fn verify_gkr_proof( + in0: String, + in1: Vec, + in2: String, + in3: Vec, + ) -> Result { + panic!("Gkr is not enabled in this build. Please pass `gkr` feature to `mopro-ffi` to enable Gkr.") + } + }; +} + use thiserror::Error; #[derive(Debug, Error)] @@ -75,6 +102,8 @@ pub enum MoproError { CircomError(String), #[error("Halo2Error: {0}")] Halo2Error(String), + #[error("GkrError: {0}")] + GkrError(String), } #[derive(Debug, Clone)] @@ -83,6 +112,12 @@ pub struct GenerateProofResult { pub inputs: Vec, } +#[derive(Debug, Clone)] +pub struct GkrProofResult { + pub proof: Vec, + pub output_claims: String, +} + #[derive(Debug, Clone, Default)] pub struct G1 { pub x: String, @@ -142,12 +177,14 @@ pub struct ProofCalldata { macro_rules! app { () => { // These are mandatory imports for the uniffi to pick them up and match with UDL - use mopro_ffi::{GenerateProofResult, MoproError, ProofCalldata, G1, G2}; + use mopro_ffi::{GenerateProofResult, GkrProofResult, MoproError, ProofCalldata, G1, G2}; mopro_ffi::circom_app!(); mopro_ffi::halo2_app!(); + mopro_ffi::gkr_app!(); + uniffi::include_scaffolding!("mopro"); }; } From 4a7788be37ca90a3760e90054be15afadc56ed68 Mon Sep 17 00:00:00 2001 From: "Ya-wen, Jeng" Date: Wed, 2 Oct 2024 21:37:24 +0800 Subject: [PATCH 2/2] fix(ffi): fix udl --- mopro-ffi/src/mopro.udl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mopro-ffi/src/mopro.udl b/mopro-ffi/src/mopro.udl index de876538..91c4e4ae 100644 --- a/mopro-ffi/src/mopro.udl +++ b/mopro-ffi/src/mopro.udl @@ -29,6 +29,11 @@ dictionary GenerateProofResult { bytes inputs; }; +dictionary GkrProofResult { + bytes proof; + string output_claims; +}; + // dictionary BenchmarkResult { // u32 instance_size; // u32 num_instance; @@ -55,4 +60,5 @@ dictionary ProofCalldata { enum MoproError { "CircomError", "Halo2Error", + "GkrError", };