Rebuild the published PyBLØCK Android APKs yourself and confirm they match, byte-for-byte, what we ship.
This recipe lets anyone rebuild the published APKs and confirm they match what we ship. It applies to both apps — PyBLØCK (com.astrolexis.pyblock) and PyBLØCK ᛒ / BLAKE2b (com.astrolexis.pyblockblake2b) — which share the same toolchain. The source repositories are private for now; this page publishes the build recipe and verification steps so the result is independently checkable regardless.
| Version | 0.2.3 · versionCode 30 · com.astrolexis.pyblockblake2b |
| Source | gitlab.com/astrolexis-group1/pyblock-blake2b (public) |
| Commit | 0a60bf34e7ca909c3945cf77190810ef74a069de |
| Unsigned APK SHA-256 — the reproducible target | b3297ef5b28252bca68afc208251f1310fd48ef462c46505c49bdc21dcde97fd · 61.848.274 bytes |
| Published (signed) APK | pyblockblake2b-0.2.3-30.apk · SHA-256 5da04a23bdefd6242465818a50f61db77d9cea71f9b160c25ce1a21bfe55ebdc · 61,864,658 bytes |
Built on a clean Linux host in Docker (Temurin 17 · SDK platform-35 / build-tools 35.0.0 · Gradle 8.11.1 wrapper) with strict dependency verification. Two independent clean assembleRelease runs produced the identical unsigned SHA-256 above — the build is deterministic. The published signed APK equals that unsigned APK plus the APK signature block (see §5).
Cargo.toml, no .so are compiled or committed here.libbdkffi, libsecp256k1-jni) come prebuilt from Maven as immutable released artifacts:
org.bitcoindevkit:bdk-android:3.0.0fr.acinq.secp256k1:secp256k1-kmp-jni-android:0.18.0Their byte-for-byte reproducibility is an upstream concern (Bitcoin Dev Kit / ACINQ). We pin them to an exact version and verify each artifact by SHA-256 (see §3).
Identical for both apps:
| Component | Version |
|---|---|
| JDK (build) | Temurin/OpenJDK 17.0.20 |
| Android Gradle Plugin | 8.7.3 |
| Gradle (wrapper) | 8.11.1 |
| Kotlin (android + compose + serialization) | 2.3.10 |
| compileSdk / targetSdk | 35 / 35 · build-tools 35.0.0 |
| Jetpack Compose | BOM 2024.12.01 |
| Packaged ABIs | arm64-v8a, armeabi-v7a, x86_64 |
| R8 / minify | off — no obfuscation variance |
gradle/verification-metadata.xml records the SHA-256 of every resolved artifact, including the prebuilt native .so from the Maven dependencies above. Gradle verifies these on every build; a mismatch fails the build. Regenerate or inspect with:
./gradlew --write-verification-metadata sha256 assembleRelease
./gradlew clean assembleRelease
# → app/build/outputs/apk/release/app-release.apk
A keystore is only needed to sign; the unsigned APK content is what you compare.
The signing block differs by signer by design (v2 + v3 schemes, our key), so compare the unsigned APK:
apksigcopier extract published.apk sig.zip # or strip the v2/v3 block
diffoscope your-unsigned.apk published-unsigned.apk
Published APKs are signed with APK Signature Scheme v2 + v3 (same key; v3 enables future key rotation via a lineage without users reinstalling). Certificate SHA-256 digests, unchanged across releases:
Verify with:
apksigner verify -v --print-certs the.apk
# → Verified using v2 scheme: true · v3 scheme: true · digest as above