Skip to main content

Announcing the ETHGlobal Cannes 2025 Mopro Track Winners: Advancing Mobile Proving

· 6 min read
Moven Tsai
Developer on the Mopro Team

ETHGlobal Cannes brought together some of the brightest minds in blockchain development, and we're thrilled to announce the winners of the Mopro track. Over 36 intense hours, developers pushed the boundaries of client-side proving with real-world applications on mobile device.

With innovative submissions ranging from protocol-level integrations to consumer-facing applications, Mopro track showed how mobile ZK proving is becoming increasingly practical. Teams leveraged Mopro's mobile proving capabilities to build everything from tamper-proof media verification to post-quantum secure smart accounts with EIP-7702, proving that privacy-preserving technology can be both powerful and user-friendly.

The Power of Client-Side Proving

Before diving into the winners, it's worth highlighting what made this hackathon special. While many ZK applications rely on server-side proving or trusted execution environments (TEEs), Mopro enables developers to generate zero-knowledge proofs directly on mobile devices. This approach puts privacy control back in users' hands and opens up new possibilities for decentralized applications.

The submissions demonstrated two key trends: protocol developers integrating zkVM such as RISC-0 and libraries like Gnark with Mopro, and application developers building user-facing products that leverage existing ZK circuits. Both approaches are critical for the ecosystem's growth.

The Winners

🥇 First Place: Mobiscale - Photo-ID Verification with Apple's Secure Enclave

Project: Mobiscale
GitHub: ElusAegis/MobiScale

Mobiscale achieved what many thought impossible in a hackathon setting: a complete end-to-end proof of photo-ID verification running entirely on a mobile device in under 90 seconds. The team cleverly combined Apple's Secure Enclave for facial recognition, RISC-0 for TEE attestation verification, and Noir with the Barretenberg proving backend for ECDSA signature validation.

What makes this project remarkable is its practical approach to identity verification. By computing cosine similarity between a passport photo and a live selfie within the TEE, then proving this computation happened correctly using ZK proofs, Mobiscale demonstrates a privacy-preserving liveness check that could be deployed in the near future. The integration with Mopro shows how mobile proving can complement hardware security features to create robust identity solutions.

🥈 Second Place: Zkipper - PQ-Secure EIP-7702 Smart Accounts

Project: Zkipper
GitHub: ZKNoxHQ/ZKipper

The ZKNox team showcased their cryptographic expertise at the hackathon with "Zkipper," a project that turns the ARX chips in ETHGlobal wristbands into transaction signers, enabling post‑quantum–secure smart accounts via EIP‑7702.

The technical achievement here is twofold: First, they successfully integrated Gnark with Mopro within the 36-hour timeframe, which is a significant contribution to the ecosystem. Second, they implemented Falcon512 post-quantum signatures to secure smart accounts, preventing "Bybit-style" attacks by separating admin commands onto distinct devices. This approach shows how Mopro can enable hardware-based security solutions that are both quantum-resistant and user-friendly.

🥉 Third Place: 👀Proov! - Tamper-Proof Media with ZK

Project: 👀Proov!
GitHub: undefinedlab/PROOV_ZK

👀Proov! stood out not just for its technical implementation but for its exceptional UI/UX design. The team created a complete solution for tamper-proof media capsules, combining Mopro-generated proofs with AI-powered image summaries, decentralized storage on Walrus, and verification on Flow blockchain.

The project offers one-tap proof generation with instant cryptographic capsule creation, selective privacy controls, and future-disclosure capabilities. By embedding tamper-proof QR codes in image capsules, they made every photo machine-verifiable and portable across platforms like Instagram, X, and Telegram. This shows how ZKP can be packaged into consumer-friendly applications without sacrificing security or privacy.

Other Notable Submissions

Beyond the top three winners, the Mopro track at ETHGlobal Cannes attracted submissions that collectively show the diversity of ZK use cases on mobile. Teams explored verification and attestation use cases through projects like ProofOfParticipation (GPS-based event attendance), ZKAge Proof Mobile (age verification for restricted services). Bidet's privacy-preserving NFC tag game showcased gaming and social use cases, and ProofOfFunds showed financial privacy by letting users prove they meet a cryptocurrency balance threshold without disclosing exact amounts or wallet addresses.

These submissions integrated various technical stacks across different proving frameworks—Circom and Noir—and mobile platforms—Swift (iOS), Kotlin (Android), React Native, and Flutter—alongside Mopro’s proving capabilities. This integration validates the platform’s flexibility across use cases and tech stacks. The diversity of both applications and technical aspect highlights the ecosystem’s readiness for real-world deployment and shows how mobile proving can address privacy challenges across multiple industries.

Key Insights and Developer Feedback

The hackathon provided valuable insights into the state of mobile ZK proving:

What's Working Well:

  • Mopro's developer experience received consistently positive feedback
  • Teams successfully integrated various proving systems (RISC-0, Noir, Gnark) with Mopro
  • The ecosystem is mature enough for developers to build meaningful applications in 36 hours

Challenges Identified:

  • Writing circuits remains the biggest pain point for developers
  • On-chain verification varies in stability (Circom is more mature, Noir is catching up)
  • Developers need single-architecture templates for iOS-only or Android-only builds

Looking Forward: The Future of Client-Side Proving

The diversity of submissions—from geo-proof games adapted from zkVerify's proof-of-geolocation circuits to age verification systems—shows that mobile ZK proving is ready for mainstream adoption. While Mopro may not pursue the same level of direct adoption as protocols aimed at end users, it serves a critical role as an incubation platform for client-side ZK applications especially on mobile phone.

Based on developer feedback, we're prioritizing several improvements:

  • Enhanced Templates - Expanding variety for different use cases (Issue #503, Issue #438)
  • Single Architecture Support - iOS-only and Android-only bindings for cross-platform frameworks like Flutter (Issue #502) and React Native (Issue #501).
  • Improved DevEx - Better naming for custom bindings (Issue #500)
  • Documentation - Simplified architecture overview (Issue #498)

Acknowledgments

We'd like to thank all teams who participated in the Mopro track at ETHGlobal Cannes. Your innovation, dedication, and feedback are invaluable in advancing the state of mobile proving.

Special recognition goes to the ETHGlobal team for organizing an exceptional event and providing the infrastructure that makes these innovations possible.

Get Involved

The work showcased at ETHGlobal Cannes is just the beginning. If you're interested in building with Mopro or contributing to the ecosystem:

Metal MSM v2: Exploring MSM Acceleration on Apple GPUs

· 12 min read
Moven Tsai
Developer on the Mopro Team

Key Takeaways

  • Hybrid CPU-GPU approaches are essential for fully exploiting limited hardware such as mobile devices, improving MSM computation and accelerating proof generation.
  • To unify GPU acceleration efforts, WebGPU's vendor-agnostic API and WGSL offer promising solutions that compile to native formats like SPIR-V (for Vulkan on Android) and MSL (for Metal on Apple devices).
  • GPU acceleration for post-quantum proving systems could enable their widespread adoption.

Introduction

GPU acceleration harnesses the massive parallelism of Graphics Processing Units (GPUs) to dramatically speed up tasks that would otherwise overwhelm traditional CPUs. Because GPUs can execute thousands of threads simultaneously, they have become indispensable for compute-intensive workloads such as machine-learning model training and modern cryptographic algorithms.

This technology plays a crucial role in advancing privacy-preserving applications, as zero-knowledge proofs (ZKPs) currently face a significant bottleneck due to the high computational cost of their core operations. By accelerating these operations, we can generate proofs more quickly and cost-effectively, which is essential for the broader adoption of privacy-focused solutions across Ethereum and other blockchain platforms.

Currently, research on GPU acceleration for cryptography remains fragmented, with each platform relying on its own framework: Metal on Apple devices, Vulkan on Android, and CUDA on NVIDIA hardware. Aside from CUDA, most GPU frameworks lack mature ecosystems of cryptographic libraries (e.g., NVIDIA's cuPQC and cuFFT).

Therefore, Mopro is investing in GPU acceleration through related grants (Issue #21, Issue #22, and Issue #153), as it advances our mission to make mobile proving both accessible and practical.

A Primer on Multi-Scalar Multiplication

Multi-Scalar Multiplication (MSM) is an essential primitive in elliptic curve cryptography, particularly in pairing-based proving systems widely used for privacy-preserving applications. MSM involves computing a sum of the form Q=i=1n(kiPi)Q = \sum_{i=1}^{n}(k_i \cdot P_i), where kik_i are scalars and PiP_i are points on an elliptic curve, such as BN254. This computationally intensive operation is ideal for GPU acceleration.

Metal MSM v2 is an open-source implementation, licensed under MIT and Apache 2.0, that optimizes MSM on Apple GPUs using the Metal Shading Language (MSL). Building on its predecessor, Metal MSM v2 offers significant performance improvements through algorithmic and GPU-specific optimizations, laying the foundation for further research into mobile proving acceleration with GPUs.

Recap on Metal MSM v1

The first version of Metal MSM (v1) was an initial attempt to bring MSM computations on the BN254 curve to Apple GPUs, leveraging parallelism and optimizations like precomputation from the EdMSM paper by Bootle et al.1. While it showed the potential for GPU acceleration, profiling result revealed key limitations:

  • Low GPU Occupancy: At only 32%, the GPU was underutilized, leading to inefficient computation.
  • High Memory Footprint: Peak VRAM usage was excessive, causing GPU hang errors on real mobile devices for instance sizes ≥ 2^14.
  • Performance Bottlenecks: For an input size of 2^20 points, v1 took 41 seconds on an M1 Pro MacBook, indicating substantial room for improvement.

These challenges drove the development of a newer version, which introduces targeted optimizations to address these issues. For full context, refer to the detailed Metal MSM v1 Summary Report and Metal MSM v1 Profiling Report.

Metal MSM v2: What's New

Metal MSM v2 introduces key enhancements over v1, significantly improving performance and resource efficiency. It adopts the sparse matrix approach from the cuZK paper by Lu et al.2, treating MSM elements as sparse matrices to reduce memory usage and convert operations described in Pippenger's algorithm into efficient sparse matrix algorithms.

The implementation draws inspiration from Derei and Koh's WebGPU MSM implementation for ZPrize 2023. However, targeting the BN254 curve (unlike the BLS12-377 curve used by Zprize 2023) required different optimization strategies, particularly for Montgomery multiplications and for using Jacobian coordinates instead of projective or extended twisted Edwards coordinates.

Due to differences between shading languages (CUDA for cuZK, WGSL for WebGPU, and MSL for Metal), additional GPU programming efforts were necessary. For instance, dynamic kernel dispatching, which is straightforward in CUDA, required workarounds in Metal through host-side dispatching at runtime.

Key improvements include:

  • Dynamic Workgroup Sizing: Workgroup sizes are adjusted based on input size and GPU architecture using a scale_factor and thread_execution_width. These parameters were optimized through experimentation to maximize GPU utilization as mentioned in PR #86.
  • Dynamic Window Sizes: A window_size_optimizer calculates optimal window sizes using a cost function from the cuZK paper, with empirical adjustments for real devices, as detailed in PR #87.
  • MSL-Level Optimizations: Loop unrolling and explicit access qualifiers, implemented in PR #88, enhance kernel efficiency, with potential for further gains via SIMD refactoring.

Benchmarks on an M3 MacBook Air with 24GB memory show 40x–100x improvements over v1 and ~10x improvement over ICME Labs' WebGPU MSM on BN254, adapted from Derei and Koh's BLS12-377 work. While still slower than CPU-only Arkworks MSM on small & medium input sizes, v2 lays the groundwork for a future CPU+GPU hybrid approach.

How Metal MSM v2 Works

The general flow follows Koh's technical writeup. We pack affine points and scalars on the CPU into a locality-optimized byte format, upload them to the GPU, and encode points into Montgomery form for faster modular multiplications. Scalars are split into signed chunks to enable the Non-Adjacent Form (NAF) method, halving both bucket count and memory during accumulation.

Next, we apply a parallel sparse-matrix transposition (adapted from Wang et al.'s work3) to identify matching scalar chunks and group points into buckets. Then, using a sparse-matrix–vector product (SMVP) and the pBucketPointsReduction algorithm (Algorithm 4 in the cuZK paper2), we split buckets among GPU threads, compute each thread's running sum, and scale it by the required factor.

After GPU processing, we transfer each thread's partial sums back to the CPU for final aggregation. Since the remaining point count is small and Horner's Method is sequential and efficient on the CPU, we perform the final sum there.

The use of sparse matrices is a key innovation in Metal MSM v2, reducing memory requirements and boosting parallelism compared to previous approaches.

Understanding the Theoretical Acceleration Upper Bound

In the Groth16 proving system, Number Theoretic Transform (NTT) and MSM account for 70–80% of the proving time. According to Amdahl's Law, the maximum speedup is limited by unoptimized components:

Speedupoverall=1(1timeoptimized)+timeoptimizedspeedupoptimized\text{Speedup}_{\text{overall}} = \dfrac{1}{(1 - \text{time}_{\text{optimized}}) + \dfrac{\text{time}_{\text{optimized}}}{\text{speedup}_{\text{optimized}}}}

If 80% of the prover time is optimized with infinite speedup, the theoretical maximum is 5x. However, data I/O overhead reduces practical gains. For more details, see Ingonyama's blog post on Hardware Acceleration for ZKP.

Benchmark Results

Benchmarks conducted on an M3 MacBook Air compare Metal MSM v2 with the Arkworks v0.4.x CPU implementation across various input sizes.

Metal MSM v2 Benchmark Results

SchemeInput Size (ms)
212214216218220222224
Arkworks v0.4.x
(CPU, Baseline)
619692459423,31914,061
Metal MSM v0.1.0
(GPU)
143
(-23.8x)
273
(-14.4x)
1,730
(-25.1x)
10,277
(-41.9x)
41,019
(-43.5x)
555,877
(-167.5x)
N/A
Metal MSM v0.2.0
(GPU)
134
(-22.3x)
124
(-6.5x)
253
(-3.7x)
678
(-2.8x)
1,702
(-1.8x)
5,390
(-1.6x)
22,241
(-1.6x)
ICME WebGPU MSM
(GPU)
N/AN/A2,719
(-39.4x)
5,418
(-22.1x)
17,475
(-18.6x)
N/AN/A
ICICLE-Metal v3.8.0
(GPU)
59
(-9.8x)
54
(-2.8x)
89
(-1.3x)
149
(+1.6x)
421
(+2.2x)
1,288
(+2.6x)
4,945
(+2.8x)

ElusAegis' Metal MSM
(GPU)

58
(-9.7x)
69
(-3.6x)
100
(-1.4x)
207
(+1.2x)
646
(+1.5x)
2,457
(+1.4x)
11,353
(+1.2x)

ElusAegis' Metal MSM
(CPU+GPU)

13
(-2.2x)
19
(-1.0x)
53
(+1.3x)
126
(+1.9x)
436
(+2.2x)
1,636
(+2.0x)
9,199
(+1.5x)

Negative values indicate slower performance relative to the CPU baseline. The performance gap narrows for larger inputs.

Notes:

  • For ICME WebGPU MSM, input size 2^12 causes M3 chip machines to crash; sizes not listed on the project's GitHub page are shown as "N/A"
  • For Metal MSM v0.1.0, the 2^24 benchmark was abandoned due to excessive runtime.

While Metal MSM v2 isn't faster than CPUs across all hardware configurations, its open-source nature, competitive performance relative to other GPU implementations, and ongoing improvements position it well for continued advancement.

Profiling Insights

Profiling on an M1 Pro MacBook provides detailed insights into the improvements from v1 to v2:

metricv1v2gain
end-to-end latency10.3 s0.42 s24x
GPU occupancy32 %76 %+44 pp
CPU share19 %<3 %–16 pp
peak VRAM1.6 GB220 MB–7.3×

These metrics highlight the effectiveness of v2's optimizations:

  • Latency Reduction: A 24-fold decrease in computation time for 2^20 inputs.
  • Improved GPU Utilization: Occupancy increased from 32% to 76%, indicating better use of GPU resources.
  • Reduced CPU Dependency: CPU share dropped below 3%, allowing the GPU to handle most of the workload.
  • Lower Memory Footprint: Peak VRAM usage decreased from 1.6 GB to 220 MB, a 7.3-fold reduction.

Profiling also identified buffer reading throughput as a primary bottleneck in v1, which v2 mitigates through better workload distribution and sparse matrix techniques. See detailed profiling reports: v1 Profiling Report and v2 Profiling Report.

Comparison to Other Implementations

Metal MSM v2 is tailored for Apple's Metal API, setting it apart from other GPU-accelerated MSM implementations:

  • Derei and Koh's WebGPU MSM on BLS12: Designed for WebGPU, this implementation targets browser-based environments and may not fully leverage Apple-specific hardware optimizations.
  • ICME labs WebGPU MSM on BN254: Adapted from Derei and Koh's WebGPU work for the BN254 curve, it is ~10x slower than Metal MSM v2 for inputs from 2^16 to 2^20 on M3 MacBook Air.
  • cuZK: A CUDA-based implementation for NVIDIA GPUs, operating on a different hardware ecosystem and using different algorithmic approaches.

Metal MSM v2's use of sparse matrices and dynamic workgroup sizing provides advantages on Apple hardware, particularly for large input sizes. While direct benchmark comparisons are limited, internal reports suggest that v2 achieves performance on par with or better than other WebGPU/Metal MSM implementations at medium scales.

It's worth noting that the state-of-the-art Metal MSM implementation is Ingonyama's ICICLE-Metal (since ICICLE v3.6). Readers can try it by following:

Another highlight is ElusAegis' Metal MSM implementation for BN254, which was forked from version 1 of Metal MSM. To the best of our knowledge, his pure GPU implementation further improves the allocation and algorithmic structure to add more parallelism, resulting in 2x faster performance compared to Metal MSM v2.

Moreover, by integrating this GPU implementation with optimized MSM on the CPU side from the halo2curves library, he developed a hybrid approach that splits MSM tasks between CPU and GPU and then aggregates the results. This strategy achieves an additional 30–40% speedup over a CPU-only implementation. This represents an encouraging result for GPU acceleration in pairing-based ZK systems and suggests a promising direction for Metal MSM v3.

Future Work

The Metal MSM team has outlined several exciting directions for future development:

  • SIMD Refactoring: Enhance SIMD utilization and memory coalescing to further boost performance.
  • Advanced Hybrid Approach: Integrate with Arkworks 0.5 for a more sophisticated CPU-GPU hybrid strategy.
  • Android Support: Port kernels to Vulkan compute/WebGPU on Android, targeting Qualcomm Adreno (e.g., Adreno 7xx series) and ARM Mali (e.g., G77/G78/G710) GPUs.
  • Cross-Platform Support: Explore WebGPU compatibility to enable broader platform support.
  • Dependency Updates: Transition to newer versions of objc2 and objc2-metal, and Metal 4 to leverage the latest MTLTensor features, enabling multi-dimensional data to be passed to the GPU.

Beyond these technical improvements, we are also interested in:

  • Exploration of PQ proving schemes: With the limited acceleration achievable from pairing-based proving schemes, we're motivated to explore PQ-safe proving schemes that have strong adoption potential over the next 3–5 years. These schemes, such as lattice-based proofs, involve extensive linear algebra operations that can benefit from GPUs' parallel computing capabilities.
  • Crypto Math Library for GPU: Develop comprehensive libraries for cryptographic computations across multiple GPU frameworks, including Metal, Vulkan, and WebGPU, to expand the project's overall scope and impact.

Conclusion

Metal MSM v2 represents a leap forward in accelerating Multi-Scalar Multiplication on Apple GPUs. By addressing the limitations of v1 through sparse matrix techniques, dynamic thread management, and other novel optimization techniques, it achieves substantial performance gains for Apple M-series chips and iPhones.

However, two challenges remain:

  • First, GPUs excel primarily with large input sizes (typically around 2^26 or larger). Most mobile proving scenarios use smaller circuit sizes, generally ranging from 2^16 to 2^20, which limits the GPU's ability to fully leverage its parallelism. Therefore, optimizing GPU performance for these smaller workloads remains a key area for improvement.
  • Second, mobile GPUs inherently possess fewer cores and comparatively lower processing power than their desktop counterparts, constraining achievable performance. This hardware limitation necessitates further research into hybrid approaches and optimization techniques to maximize memory efficiency and power efficiency within the constraints of mobile devices.

Addressing these challenges will require ongoing algorithmic breakthroughs, hardware optimizations, and seamless CPU–GPU integration. Collectively, these efforts pave a clear path for future research and practical advancements that enable the mass adoption of privacy-preserving applications.

Get Involved

We welcome researchers and developers interested in GPU acceleration, cryptographic computations, or programmable cryptography to join our efforts:

For further inquiries or collaborations, feel free to reach out through the project's GitHub discussions or directly via our Mopro community on Telegram.

Special Thanks

We extend our sincere gratitude to Yaroslav Yashin, Artem Grigor, and Wei Jie Koh for reviewing this post and for their valuable contributions that made it all possible.

Footnotes

  1. Bootle, J., & Chiesa, A., & Hu, Y. (2022). "Gemini: elastic SNARKs for diverse environments." IACR Cryptology ePrint Archive, 2022/1400: https://eprint.iacr.org/2022/1400

  2. Lu, Y., Wang, L., Yang, P., Jiang, W., Ma, Z. (2023). "cuZK: Accelerating Zero-Knowledge Proof with A Faster Parallel Multi-Scalar Multiplication Algorithm on GPUs." IACR Cryptology ePrint Archive, 2022/1321: https://eprint.iacr.org/2022/1321 2

  3. Wang, H., Liu, W., Hou, K., Feng, W. (2016). "Parallel Transposition of Sparse Data Structures." Proceedings of the 2016 International Conference on Supercomputing (ICS '16): https://synergy.cs.vt.edu/pubs/papers/wang-transposition-ics16.pdf

Mopro x Noir: Powering Mobile Zero-Knowledge Proofs

· 11 min read
Vivian Jeng
Developer on the Mopro Team

Introduction

Noir has been gaining significant traction recently, and for good reason. It's renowned for its elegant circuit frontend design and high-performance backend. With robust SDKs that make building web-based zero-knowledge apps seamless—and the ability to verify proofs on-chain—Noir stands out as a powerful and promising framework for developing modern ZKP applications.

However, while Noir offers strong support for web-based applications, native mobile support is still limited within the ecosystem. Most existing resources for mobile development have been contributed by the zkPassport team, including key projects like

Our work is deeply inspired by the zkPassport team’s contributions, but builds upon them with significant improvements and optimizations.

In this article, we’ll walk through how we integrated Noir into the Mopro project, highlighting the key challenges we faced and the opportunities we uncovered along the way. We'll also introduce Stealthnote Mobile, a fully native mobile application built with Noir, to demonstrate the potential and performance of running zero-knowledge proofs natively on mobile devices.

Build noir-rs

Like many apps with Mopro, our journey began with building a Rust crate. We started by adopting noir_rs from the zkPassport team. However, we quickly ran into some major challenges: compiling the Barretenberg backend — the proving system used by most Noir projects — could take up to 20 minutes. On top of that, the build process required a very specific developer environment, and lacked caching, meaning the entire binary had to be rebuilt from scratch even after a successful build.

To address these issues, we introduced a solution in

by prebuilding the backend binaries and hosting them on a server. During the build process, these binaries are downloaded automatically, eliminating the need for local compilation. This approach drastically reduces build time—from 20 minutes to just 8 seconds—and removes the need for any special environment setup. In fact, you can see from our GitHub Actions YAML file that no additional dependencies are required.

Suggestions

Currently, the build process for the backend happens locally, which makes it non-reproducible and difficult to upgrade in CI environments like GitHub Actions. To improve this, we believe the build logic should be moved into CI. However, this process is quite complex and largely duplicated across repositories like the Noir and Aztec packages (See: publish-bb.yml).

Our proposal is that the Noir and Aztec teams consolidate this effort by building libbarretenberg.a within the same CI pipeline and releasing them. Since bb depends on these static libraries, they would naturally be compiled as part of that process. These prebuilt artifacts could then be published alongside the bb binary. This would allow downstream consumers like noir-rs to directly use the published binaries, eliminating the need to maintain custom build scripts or host binaries separately.

note

bb is a CLI tool that generates proofs directly in the user's terminal. Underneath, it relies on libbarretenberg.a—a static library that exposes low-level function APIs for proof generation, e.g.

void acir_prove_ultra_honk(uint8_t const* acir_vec,
bool const* recursive,
uint8_t const* witness_vec,
uint8_t** out)

When properly linked, this library can be used directly within a Rust program, enabling seamless integration of the proving system into native applications.

Go Mobile-Native

Once we have the Rust crate ready, integrating it into a Mopro project allows us to easily generate bindings for both iOS and Android. Mopro significantly improves the mobile integration experience in the following ways:

  1. No additional Swift or Kotlin bindings required

    Unlike the zkPassport team's approach—where they built separate Swoir and noir_android libraries with custom domain-specific interfaces—Mopro leverages uniffi to automatically generate language bindings. This means developers don’t need to manually maintain Swift 1 or Kotlin wrappers 2; they can directly import and use the generated bindings in their mobile codebases. e.g.

    For swift:

    import moproFFI

    let proofData = try! generateNoirProof(circuitPath: zkemailCircuitPath, srsPath: zkemailSrsPath, inputs: inputs)

    For kotlin:

    import uniffi.mopro.generateNoirProof

    let proofData = generateNoirProof(circuitFile, srsPath, inputs)
  2. Framework-Agnostic Design

    Mopro is not tied to any specific mobile framework. By defining reusable templates for each target framework, developers are free to choose the environment they’re most comfortable with. Currently, Mopro supports native iOS (Xcode + Swift), native Android (Android Studio + Kotlin), as well as cross-platform frameworks like React Native and Flutter—offering maximum flexibility and accessibility for diverse developer needs.

Mopro Support

We’ve successfully integrated Noir proving into both Mopro-FFI and the Mopro CLI. You can now install the Mopro CLI and follow the steps in the Getting Started guide to create a Noir project. Simply replace the SRS and circuit files with your own, and provide your custom circuit input — that’s it!

We’ve also provided an example zkEmail repository featuring a Noir circuit

along with a NoirHack workshop video.

Feel free to explore the repo, clone it, and follow along to learn how to use Noir with Mopro in a real-world application.

Challenge: Cross-platform support is limited

Our current implementation draws heavily from the zkPassport team’s work, which currently supports iOS devices and ARM64 Android devices/emulators. However, there are limitations: iOS simulators—essential for efficient development and testing—are not supported, and many Android developers (especially those using Windows with WSL) rely on x86_64 emulators. Even CI environments like GitHub Actions commonly use x86_64 Android emulators.

PlatformsCurrent support targetSupport
iOSaarch64-apple-ios
iOSaarch64-apple-ios-sim
iOSx86_64-apple-ios
Androidx86_64-linux-android
Androidi686-linux-android
Androidarmv7-linux-androideabi
Androidaarch64-linux-androids
MacOSstable-aarch64-apple-darwin
Linuxx86_64-unknown-linux-gnu
Windowsx86_64-pc-windows-msvc

Expanding support to these platforms is a significant challenge. The barretenberg backend, written in C++ and built with CMake, is large and complex, making cross-compilation non-trivial. While we’re evaluating the effort required to support additional architectures, we’re also hopeful that the Noir or zkPassport teams may address this gap in the future.

Case Study: Stealthnote Mobile App

During the NoirHack 2025 (April 14th to May 10th), the Mopro team participated by building a mobile-native Noir application. Our project was inspired by Stealthnote, originally created by Saleel. Stealthnote is a web-based app that allows users to sign in with Google OAuth and prove ownership of their organizational email address. It leverages a Noir circuit to generate a zero-knowledge proof from the JWT issued by Google OAuth. You can read more about the original project in Saleel’s blog post.

We aim to enhance performance and user experience by building a fully native mobile app. At the same time, we want to demonstrate that the current Mopro + Noir stack is fully capable of supporting mobile-native development. Therefore, we decided to build a mobile version of Stealthnote.

What We Built

During the hackathon, we developed

A mobile-native frontend for the original Stealthnote project. To maintain compatibility, we kept the original Noir circuits and backend logic intact, focusing entirely on building the mobile frontend. Even so, creating a mobile frontend involved tackling many challenges across platforms.

We chose Flutter as our cross-platform framework because of its fast build times compared to React Native and its rich ecosystem of packages for mobile functionalities—such as Google authentication, biometric login, camera access, gallery browsing, and file storage. In our view, Flutter is currently the best choice for building high-performance, cross-platform apps.

Our architecture separates responsibilities clearly:

  • Flutter handles:

    1. UI/UX design
    2. Google OAuth authentication
    3. Backend API communication
  • Rust handles:

    1. Parsing the JWT and converting it into the structured inputs required by the Noir circuit
    2. Generating and verifying Noir proofs
    3. Ephemeral key generation using Ed25519 and Poseidon2
    info

    To learn how to integrate Mopro Rust bindings into a Flutter project, please refer to the

This clear separation lets us leverage the strengths of both technologies—Flutter’s frontend speed and flexibility, and Rust’s performance and security for core cryptographic logic.

Benchmark

While the Mopro team anticipated the outcome, the benchmark results are still notable: a mobile-native prover delivers performance up to 10 times faster than running the same proof in a browser environment.

JWT OperationProveVerify
Browser37.292 s0.286 s
Desktop (Mac M1 Pro)2.02 s0.007 s
Android emulator (Pixel 8)4.786 s3.013 s
iPhone 16 Pro2.626 s1.727 s

Challenge: Insufficient Rust tooling and SDKs.

One of the main challenges we faced was converting all the TypeScript functions used in StealthNote into their Rust equivalents. For standard cryptographic operations like Ed25519 signatures, this was relatively straightforward — Rust has mature libraries we could rely on.

However, Poseidon2 presented a bigger challenge. Unlike the original Poseidon hash, Poseidon2 is a newer variant used in the Noir circuits. Unfortunately, there was no direct Rust implementation available. The Noir team primarily supports a TypeScript version via bb.js, which is a wrapper around Barretenberg's C++ implementation compiled to WASM. This made it hard to fully understand the logic and port it to Rust.

Eventually, we located the Poseidon2 Noir circuit and its permutation logic in the noir-lang repository. Using that as a reference, we implemented our own version of

aligning it with the Noir circuit to ensure compatibility.

Suggestions

Since Barretenberg already provides a C++ implementation for most Noir circuit functions, it would actually be more efficient and sustainable for the Noir or Aztec team to maintain a native C++ or Rust SDK for Rust developers — rather than focusing primarily on the JavaScript (bb.js) interface.

As we suggested earlier, an ideal solution would be for the team to publish precompiled static binaries (e.g. libbarretenberg.a) alongside versioned releases. This way, other developers — like us — could easily integrate these binaries into their Rust projects using proper FFI bindings.

This approach would remove the need for every developer to rebuild Barretenberg from source or maintain their own custom builds. For example, our bb.rs project demonstrates this idea, but it still lacks many of the standard library features available in bb.js, such as: poseidon2, blake2, AES encryption/decryption. Providing official support for these as native libraries would greatly improve the developer experience and adoption for building performant, mobile-native or server-side ZK applications.

Conclusion

We began integrating Noir with Mopro in early April, and the process progressed smoothly — thanks in large part to the foundational work done by the zkPassport team. In contrast to our experience with the Circom prover (which took several months to make mobile-compatible), Noir integration was faster and more straightforward.

However, we also discovered significant gaps in Noir’s current support for mobile-native development. While the prover itself is crucial, a complete SDK ecosystem is equally important. At the moment, teams aiming to build mobile-native apps — like zkPassport — must develop many of the components from scratch, rather than being able to rely on official tooling or prebuilt libraries from the Noir team.

This raises a challenge: what if a project doesn’t have the expertise, time, or resources to build and maintain a mobile-native infrastructure? These barriers can prevent great ideas from becoming usable apps.

There’s still a long road ahead — for both the Mopro team and the Noir ecosystem — to provide a full suite of mobile-native infrastructure that can empower ZK developers, whether they're building the next zkPassport or an entirely new kind of app.

Finally, we want to encourage more developers to explore building mobile-native apps. These platforms offer better performance, deeper device integration, and more seamless user experiences — which are essential if you want your ZK project to truly reach users.

Contribution

All kinds of contributions are welcome! 🎉

Feel free to check out the current issues on the Mopro GitHub repository, or open a new issue if you notice something missing or have ideas to improve the project.

Here are some current Noir-related issues worth exploring:

Feel free to reach out to the Mopro team on Telegram @zkmopro for questions or support, and follow us on X (formerly Twitter) @zkmopro to stay up to date with our latest progress!

Footnotes

  1. Noir Swift wrapper: https://github.com/Swoir/Swoir/blob/main/Sources/Swoir/Circuit.swift

  2. Noir Kotlin wrapper: https://github.com/madztheo/noir_android/blob/main/lib/src/main/java/com/noirandroid/lib/Circuit.kt