Oumuamua Labs

ZK Toolkit for iOS & Android

Compile a Rust prover crate into a signed .xcframework and .aar with a typed Swift / Kotlin surface. Mobile teams consume one await per prove with structured cancellation. Zero ZK terminology leaks across the FFI boundary.

Why it exists

A multi-second prove on the main thread freezes the UI. On a background queue without cooperative cancellation, iOS sends SIGABRT when the app suspends; Android kills the process when the user navigates away. Manual FFI plumbing means every call site reinvents Task hopping, cancel-token wiring, and panic translation.

This toolkit ships that plumbing once, in the wrapper layer, so the call site sees only try await MyProver.prove(inputs:) (Swift) or MyProver.prove(inputs, Dispatchers.Default) (Kotlin). The wrapper is ~30 lines of Swift and one suspending extension in Kotlin, small enough to read in full.

What it does

Pipeline

cargo xtask ios-build cross-compiles the prover crate to aarch64-apple-ios and aarch64-apple-ios-sim, wraps each slice into a framework, rewrites LC_LOAD_DYLIB against @rpath, generates Swift bindings via uniffi-bindgen, assembles two .xcframework bundles (the dev crate and HekateProverCdylib), and codesigns with $HEKATE_IOS_TEAM_ID.

cargo xtask android-build cross-compiles via cargo-ndk, generates Kotlin bindings, injects System.loadLibrary("hekate_prover_cdylib") into the generated Kotlin (anchored to UniFFI's IntegrityCheckingUniffiLib codegen so an upstream bump fails a fixture test), and packs jniLibs/<abi>/*.so into a single .aar via Gradle.

SDKs

Trust model

The prover cdylib is fetched at the dev's cargo build time from the Oumuamua CDN, with Ed25519 + ML-DSA-65 signatures verified against pinned publisher keys. Once the cdylib lands inside the dev's .xcframework / .aar, Apple notarization and Play signing cover the entire app bundle; the original publisher signatures do not ride along, by design.