We attempted to reproduce the Play Store release of Bitkit v2.2.0 (to.bitkit) as part of
WalletScrutiny's automated verification pipeline.
Build succeeded. The build command ./gradlew bundleMainnetRelease --no-build-cache --no-configuration-cache completed in ~7 minutes using JDK 17 (Zulu), Android SDK build-tools 35/36, and bundletool v1.17.2 to extract split APKs from the produced AAB.
Commit: e6cd61e (tag v2.2.0)
Split APK Comparison Results
| Split |
Result |
base.apk |
✅ Identical (modulo Play Store signing artifacts) |
split_config.xxhdpi.apk |
✅ Identical (modulo Play Store signing artifacts) |
split_config.arm64_v8a.apk |
❌ 4 native libraries differ |
Non-reproducible files in split_config.arm64_v8a.apk
lib/arm64-v8a/libbitkitcore.so
lib/arm64-v8a/libdatastore_shared_counter.so
lib/arm64-v8a/libjnidispatch.so
lib/arm64-v8a/libpubky_app_specs-90a3a8b6be1a7a22.so ← new in v2.2.0
The same three libraries also differed in our v2.1.2 verification. libpubky_app_specs is new in v2.2.0.
All AndroidManifest.xml, resources.arsc, META-INF/, and stamp-cert-sha256 differences are Play Store injection artifacts and are excluded from this finding.
Likely Causes
libbitkitcore.so and libpubky_app_specs are Rust/native libraries distributed via GitHub Packages AARs (com.synonym:bitkit-core-android, etc.). If the AARs themselves were not built reproducibly, the embedded .so files will differ regardless of how the app build is reproduced.
libdatastore_shared_counter.so and libjnidispatch.so may differ due to how Play Store packages .so files vs. what bundletool extracts from a locally built AAB.
We have not yet run diffoscope on the differing libraries. If the developers can point to
reproducible-build documentation or upstream CI for the native AARs, that would help narrow the
root cause.
Environment
- Script:
bitkit_build.sh v0.3.6 (WalletScrutiny build scripts)
- Container image:
bitkitwallet_build_env:3 (Ubuntu 22.04, Zulu JDK 17, Android SDK build-tools 35
+ 36)
- Runtime: Podman on Ubuntu 24.04
We attempted to reproduce the Play Store release of Bitkit v2.2.0 (
to.bitkit) as part ofWalletScrutiny's automated verification pipeline.
Build succeeded. The build command
./gradlew bundleMainnetRelease --no-build-cache --no-configuration-cachecompleted in ~7 minutes using JDK 17 (Zulu), Android SDK build-tools 35/36, and bundletool v1.17.2 to extract split APKs from the produced AAB.Commit: e6cd61e (tag
v2.2.0)Split APK Comparison Results
base.apksplit_config.xxhdpi.apksplit_config.arm64_v8a.apkNon-reproducible files in split_config.arm64_v8a.apk
lib/arm64-v8a/libbitkitcore.solib/arm64-v8a/libdatastore_shared_counter.solib/arm64-v8a/libjnidispatch.solib/arm64-v8a/libpubky_app_specs-90a3a8b6be1a7a22.so← new in v2.2.0The same three libraries also differed in our
v2.1.2verification.libpubky_app_specsis new inv2.2.0.All
AndroidManifest.xml,resources.arsc,META-INF/, andstamp-cert-sha256differences are Play Store injection artifacts and are excluded from this finding.Likely Causes
libbitkitcore.soandlibpubky_app_specsare Rust/native libraries distributed via GitHub Packages AARs (com.synonym:bitkit-core-android, etc.). If the AARs themselves were not built reproducibly, the embedded .so files will differ regardless of how the app build is reproduced.libdatastore_shared_counter.soandlibjnidispatch.somay differ due to how Play Store packages .so files vs. whatbundletoolextracts from a locally built AAB.We have not yet run diffoscope on the differing libraries. If the developers can point to
reproducible-build documentation or upstream CI for the native AARs, that would help narrow the
root cause.
Environment
bitkit_build.shv0.3.6 (WalletScrutiny build scripts)bitkitwallet_build_env:3(Ubuntu 22.04, Zulu JDK 17, Android SDK build-tools 35+ 36)