Skip to content

Repository files navigation

QuorumPony for Android

Split a secret into printable cards. Any K of N recover it. Fully offline.

This is the Android port of QuorumPony (iOS). It splits a secret — an age or GPG key, a seed phrase, a password — into N shares using Shamir's Secret Sharing over GF(2⁸), prints them as cards (QR + hand-typeable Crockford base32), and recovers them by camera or keyboard.

Layout

Module What it is
:core QuorumPonyCore, Kotlin port. Pure JVM — no Android dependencies. GF(2⁸), Shamir split/combine, the QPW1 envelope, QPS1 share framing, Crockford base32.
:app Jetpack Compose app: split, recover (CameraX + ZXing scanning), check-a-card, printable PDF export, biometric lock, six languages.

Cross-implementation correctness

The Swift core, the Python reference (qpref.py), and this Kotlin port all verify against the same committed vector file, core/src/test/resources/test_vectors.json — byte-for-byte share equality, not just round-trips. Two independent implementations agreeing is stronger evidence than one implementation compiled twice; that is the property that matters for a format where a bug means a permanently unrecoverable backup.

./gradlew :core:test        # runs the ported unit tests + vector pins

The deterministic RNG used by the vectors is defined as the continuous keystream SHA-256(seed ‖ counter_be64), consumed in a fixed order (setID → envelope pad → per-byte coefficients). Production splits use SecureRandom.

Building

Requires JDK 17+ and the Android SDK (compileSdk 35). Then:

./gradlew :app:assembleDebug

Release builds are unsigned by design — F-Droid signs its own builds, and local releases should be signed with your own keystore.

Design decisions (matching the iOS app and its v2 plan)

  • QR generation: Nayuki's QR-Code-generator (MIT) — explicit error correction control, no dependencies; the same generator family the iOS 2.0 plan pins for byte-identical output across platforms.
  • QR scanning: CameraX + ZXing core (Apache-2.0, pure Java). No native .so libraries, which keeps F-Droid reproducibility simple. QPS1 share QRs are far below version-40 density, where ZXing is weakest; if the v2 Paper Archive lands on Android, revisit zxing-cpp vs BoofCV per the plan.
  • PDF: android.graphics.pdf.PdfDocument — platform API, real embedded fonts, zero APK cost. US Letter geometry mirrors the iOS CardPDF.
  • Biometric: androidx.biometric 1.1.0 with device-credential fallback, and the same fail-open rule as iOS: a device with no lock configured never locks the user out of their own backups.
  • No network permission. Nothing to toggle, nothing to audit.
  • Localization uses standard Android resources generated from the iOS string table (en, es, de, fr, ja, pt-BR) with in-app switching via per-app locales.

F-Droid

  • Licence: Apache-2.0 (SPDX in every file).
  • No Play Services, Firebase, analytics, or proprietary blobs; all dependencies are FLOSS from Maven Central / Google's repo.
  • Reproducibility: dependenciesInfo disabled, resource optimizations off, unsigned release artifacts.
  • Store listing metadata lives in fastlane/metadata/android/ (six locales).
  • A starting fdroiddata recipe is in metadata/app.quorumpony.yml.example.

Play Store

./gradlew :app:bundleRelease produces the AAB. Data-safety form: no data collected, no data shared; the camera is used only for on-device QR scanning.

Licence

Apache-2.0. See LICENSE.

About

Android port of QuorumPony — split a secret into printable cards with Shamir's Secret Sharing; any K of N recover it. Fully offline.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages