bePYBLØCKᛒ
Android · Reproducible Build

Reproducible Build

Rebuild the published PyBLØCK Android APKs yourself and confirm they match, byte-for-byte, what we ship.

Apps PyBLØCK · PyBLØCK ᛒToolchain JVM/Kotlin + AGPDeps SHA-256 pinnedSigning v2 + v3
Recipe first

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.

Latest verified build · PyBLØCK ᛒ (BLAKE2b)
Version0.2.3 · versionCode 30 · com.astrolexis.pyblockblake2b
Sourcegitlab.com/astrolexis-group1/pyblock-blake2b (public)
Commit0a60bf34e7ca909c3945cf77190810ef74a069de
Unsigned APK SHA-256 — the reproducible targetb3297ef5b28252bca68afc208251f1310fd48ef462c46505c49bdc21dcde97fd · 61.848.274 bytes
Published (signed) APKpyblockblake2b-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).

1 What we do & do not compile

Their 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).

2 Toolchain pins

Identical for both apps:

ComponentVersion
JDK (build)Temurin/OpenJDK 17.0.20
Android Gradle Plugin8.7.3
Gradle (wrapper)8.11.1
Kotlin (android + compose + serialization)2.3.10
compileSdk / targetSdk35 / 35 · build-tools 35.0.0
Jetpack ComposeBOM 2024.12.01
Packaged ABIsarm64-v8a, armeabi-v7a, x86_64
R8 / minifyoff — no obfuscation variance

3 Dependency pinning

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

4 Build

./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.

5 Verify against the published APK

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
Do not report "does not reproduce" because of the signature — only the signed block should differ. The goal is a byte-identical unsigned APK given the pins in §2 and the same Maven artifacts (verified by §3).

6 Signing

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:

PyBLØCK (main)  e80718578e4a6671c16a5e9b6f28e6d8fb6c362aa3cbeb2b87507429bf3cb1d6
PyBLØCK ᛒ (BLAKE2b)  e86002aa3ac72325099f92065ec8ab3b7adc70db9e74514ebd53c78acdba3fb5

Verify with:

apksigner verify -v --print-certs the.apk
# → Verified using v2 scheme: true · v3 scheme: true · digest as above
Licensed under the Apache License 2.0 · Copyright 2026 AstroLexis LLC
ᛒ PyBLØCK · b.pyblock.xyz