Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reproducible Builds are broken #13565

Open
4 tasks done
obfusk opened this issue May 17, 2024 · 8 comments
Open
4 tasks done

Reproducible Builds are broken #13565

obfusk opened this issue May 17, 2024 · 8 comments
Labels

Comments

@obfusk
Copy link

obfusk commented May 17, 2024


Bug description

Building an APK using the provided instructions and docker container results in APKs with differences in classes*.dex (and baseline.profm) compared to the official APKs published on Google Play (play flavour) and updates.signal.org (website flavour).

NB: I have found zero evidence of any kind of compromise. Some differences are yet unexplained but everything I found seems to be benign. I am disappointed that Reproducible Builds have been broken for months but I have zero reason to doubt Signal's security in any way.

Steps to reproduce

Actual result:

APKs with differences in classes*.dex (and baseline.profm).

(Also baseline.prof but that's a result of it containing a checksum for the differing .dex files.)

Expected result:

Identical APKs (except for the APK/JAR signature and possibly the baseline.profm).

Details

classes*.dex: non-deterministic order in Project.languageList() in app/build.gradle.kts

Introduced by ac5d0bf on Dec 4, 2023 and apparently unnoticed since.

The old app/build.gradle code used .sort():

def autoResConfig() {
    def files = []
    allStringsResourceFiles { f ->
        files.add(f.parentFile.name)
    }
    ['en'] + files.collect { f -> f =~ /^values-([a-z]{2,3}(-r[A-Z]{2})?)$/ }
            .findAll { matcher -> matcher.find() }
            .collect { matcher -> matcher.group(1) }
            .sort()
}

The new app/build.gradle.kts code is missing .sorted(), resulting in a non-deterministic order as "The order of the files in a FileTree is not stable, even on a single computer.".

fun Project.languageList(): List<String> {
  return fileTree("src/main/res") { include("**/strings.xml") }
    .map { stringFile -> stringFile.parentFile.name }
    .map { valuesFolderName -> valuesFolderName.replace("values-", "") }
    .filter { valuesFolderName -> valuesFolderName != "values" }
    .map { languageCode -> languageCode.replace("-r", "_") }
    .distinct() + "en"
}

Should be e.g.:

fun Project.languageList(): List<String> {
  return fileTree("src/main/res") { include("**/strings.xml") }
    .map { stringFile -> stringFile.parentFile.name }
    .map { valuesFolderName -> valuesFolderName.replace("values-", "") }
    .filter { valuesFolderName -> valuesFolderName != "values" }
    .map { languageCode -> languageCode.replace("-r", "_") }
    .distinct().sorted() + "en"
}

Relevant part of dexdump diff:

 | org.thoughtcrime.securesms.BuildConfig.<clinit>:()V
-|: const-string/jumbo v0, "uk"
-|: const-string/jumbo v1, "mk"
-|: const-string v2, "ar"
-|: const-string v3, "ko"
-|: const-string v4, "da"
-|: const-string v5, "bn"
-|: const-string/jumbo v6, "nb"
-|: const-string/jumbo v7, "lt"
-|: const-string v8, "bs"
-|: const-string v9, "gu"
-|: const-string/jumbo v10, "yue"
-|: const-string/jumbo v11, "tr"
-|: const-string/jumbo v12, "te"
-|: const-string v13, "fi"
-|: const-string/jumbo v14, "ro"
-|: const-string v15, "hi"
-|: const-string v16, "ja"
-|: const-string v17, "bg"
-|: const-string v18, "kn"
-|: const-string v19, "km"
-|: const-string v20, "af"
-|: const-string v21, "et"
-|: const-string v22, "in"
-|: const-string/jumbo v23, "sq"
-|: const-string/jumbo v24, "zh_HK"
-|: const-string v25, "fr"
-|: const-string v26, "kk"
-|: const-string/jumbo v27, "ms"
-|: const-string v28, "cs"
-|: const-string v29, "ca"
-|: const-string v30, "hu"
-|: const-string/jumbo v31, "ml"
-|: const-string v32, "el"
-|: const-string/jumbo v33, "ta"
-|: const-string/jumbo v34, "pa"
-|: const-string/jumbo v35, "th"
-|: const-string v36, "az"
-|: const-string/jumbo v37, "ug"
-|: const-string/jumbo v38, "nl"
-|: const-string/jumbo v39, "sw"
-|: const-string v40, "it"
-|: const-string v41, "de"
-|: const-string/jumbo v42, "vi"
+|: const-string v0, "es"
+|: const-string v1, "gu"
+|: const-string v2, "bn"
+|: const-string/jumbo v3, "sv"
+|: const-string v4, "ca"
+|: const-string/jumbo v5, "pt_BR"
+|: const-string/jumbo v6, "pt"
+|: const-string v7, "bs"
+|: const-string/jumbo v8, "zh_HK"
+|: const-string v9, "fa"
+|: const-string v10, "da"
+|: const-string/jumbo v11, "ml"
+|: const-string/jumbo v12, "sq"
+|: const-string/jumbo v13, "tr"
+|: const-string v14, "ja"
+|: const-string/jumbo v15, "zh_CN"
+|: const-string v16, "az"
+|: const-string/jumbo v17, "nl"
+|: const-string v18, "el"
+|: const-string v19, "et"
+|: const-string/jumbo v20, "pa"
+|: const-string/jumbo v21, "sk"
+|: const-string v22, "ar"
+|: const-string/jumbo v23, "sr"
+|: const-string v24, "kk"
+|: const-string/jumbo v25, "my"
+|: const-string/jumbo v26, "nb"
+|: const-string/jumbo v27, "vi"
+|: const-string/jumbo v28, "pl"
+|: const-string/jumbo v29, "ro"
+|: const-string/jumbo v30, "lt"
+|: const-string/jumbo v31, "ru"
+|: const-string v32, "ky"
+|: const-string/jumbo v33, "uk"
+|: const-string v34, "it"
+|: const-string v35, "ko"
+|: const-string v36, "cs"
+|: const-string v37, "fr"
+|: const-string/jumbo v38, "mk"
+|: const-string/jumbo v39, "ug"
+|: const-string/jumbo v40, "lv"
+|: const-string v41, "iw"
+|: const-string v42, "hi"
 |: const-string v43, "ga"
-|: const-string/jumbo v44, "zh_CN"
+|: const-string v44, "fi"
 |: const-string v45, "hr"
-|: const-string v46, "gl"
-|: const-string/jumbo v47, "tl"
-|: const-string/jumbo v48, "lv"
-|: const-string/jumbo v49, "my"
-|: const-string/jumbo v50, "ru"
-|: const-string v51, "ky"
-|: const-string v52, "es"
-|: const-string/jumbo v53, "sk"
-|: const-string/jumbo v54, "sv"
-|: const-string v55, "fa"
-|: const-string/jumbo v56, "sr"
-|: const-string v57, "ka"
-|: const-string v58, "eu"
-|: const-string/jumbo v59, "sl"
-|: const-string/jumbo v60, "ur"
-|: const-string/jumbo v61, "pl"
-|: const-string/jumbo v62, "pt"
-|: const-string/jumbo v63, "mr"
-|: const-string v64, "iw"
-|: const-string/jumbo v65, "zh_TW"
-|: const-string/jumbo v66, "pt_BR"
+|: const-string v46, "ka"
+|: const-string/jumbo v47, "yue"
+|: const-string v48, "hu"
+|: const-string v49, "af"
+|: const-string/jumbo v50, "th"
+|: const-string v51, "km"
+|: const-string/jumbo v52, "tl"
+|: const-string/jumbo v53, "zh_TW"
+|: const-string v54, "de"
+|: const-string v55, "eu"
+|: const-string/jumbo v56, "sl"
+|: const-string v57, "kn"
+|: const-string v58, "bg"
+|: const-string/jumbo v59, "ms"
+|: const-string/jumbo v60, "ta"
+|: const-string/jumbo v61, "te"
+|: const-string/jumbo v62, "mr"
+|: const-string v63, "gl"
+|: const-string/jumbo v64, "sw"
+|: const-string/jumbo v65, "ur"
+|: const-string v66, "in"
 |: const-string v67, "en"
 |: filled-new-array/range {v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63, v64, v65, v66, v67}, [Ljava/lang/String;

classes*.dex: unexplained differences

These differences occur in several classes*.dex files; they are identical for both play and website v7.6.2 ("variant 2") but different for play v7.7.1 ("variant 1").

Variant 1 (play v7.7.1):

   VISIBILITY_SYSTEM Ldalvik/annotation/MemberClasses; value={ Lorg/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections$ActionRestoreFromBacakupFragmentToMoreOptions; }
@@ -570943,6 +570943,23 @@
         0x0000 - 0x0004 reg=0 this Lorg/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections; 
 
     #1              : (in Lorg/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections;)
+      name          : 'actionRestartToWelcomeFragment'
+      type          : '()Landroidx/navigation/NavDirections;'
+      access        : 0x0009 (PUBLIC STATIC)
+      code          -
+      registers     : 1
+      ins           : 0
+      outs          : 0
+      insns size    : 5 16-bit code units
+| org.thoughtcrime.securesms.backup.v2.ui.restore.RestoreFromBackupFragmentDirections.actionRestartToWelcomeFragment:()Landroidx/navigation/NavDirections;
+|: invoke-static {}, Lorg/thoughtcrime/securesms/SignupDirections;.actionRestartToWelcomeFragment:()Landroidx/navigation/NavDirections;
+|: move-result-object v0
+|: return-object v0
+      catches       : (none)
+      positions     : 
+      locals        : 
+
+    #2              : (in Lorg/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections;)
       name          : 'actionRestoreFromBacakupFragmentToMoreOptions'
       type          : '(Lorg/thoughtcrime/securesms/devicetransfer/moreoptions/MoreTransferOrRestoreOptionsMode;)Lorg/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections$ActionRestoreFromBacakupFragmentToMoreOptions;'
       access        : 0x0009 (PUBLIC STATIC)

Variant 2 (play and website v7.6.2):

     #1              : (in Lorg/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections;)
-      name          : 'actionRestartToWelcomeFragment'
+      name          : 'actionRestartToWelcomeV2Fragment'
       type          : '()Landroidx/navigation/NavDirections;'
       access        : 0x0009 (PUBLIC STATIC)
       code          -
@@ -569000,8 +569000,8 @@
       ins           : 0
       outs          : 0
       insns size    : 5 16-bit code units
-| org.thoughtcrime.securesms.backup.v2.ui.restore.RestoreFromBackupFragmentDirections.actionRestartToWelcomeFragment:()Landroidx/navigation/NavDirections;
-|: invoke-static {}, Lorg/thoughtcrime/securesms/SignupDirections;.actionRestartToWelcomeFragment:()Landroidx/navigation/NavDirections;
+| org.thoughtcrime.securesms.backup.v2.ui.restore.RestoreFromBackupFragmentDirections.actionRestartToWelcomeV2Fragment:()Landroidx/navigation/NavDirections;
+|: invoke-static {}, Lorg/thoughtcrime/securesms/SignupV2Directions;.actionRestartToWelcomeV2Fragment:()Landroidx/navigation/NavDirections;
 |: move-result-object v0
 |: return-object v0
       catches       : (none)

baseline.profm

The assets/dexopt/baseline.profm file is generated non-deterministically; both a workaround and a proper fix have been available for over a year, but instead of using either apkdiff.py simply skips this file.

Upstream bug (fixed in AGP 8.1.0-alpha03):

Analysis:

Workaround:

Workaround used by Threema (until no longer needed because AGP was updated to a version with the fix):

Workaround used by Tor Browser:

apkdiff.py

Even without the reproducibility issues outlined above, use of apkdiff.py instead of producing a bit-by-bit identical APK file does not meet the definition of "Reproducible Build" as used by reproducible-builds.org.

See https://reproducible-builds.org/reports/2022-12/#android-news.

Screenshots

n/a

Device info

n/a

Link to debug log

n/a

@obfusk
Copy link
Author

obfusk commented May 18, 2024

Decompiled Java code diffs (a bit easier to read than dexdump output):

Variant 1:

--- x/classes4-enjarify/org/thoughtcrime/securesms/BuildConfig.class.java	2024-05-19 00:28:05.439481781 +0200
+++ y/classes4-enjarify/org/thoughtcrime/securesms/BuildConfig.class.java	2024-05-19 00:28:06.135487756 +0200
@@ -67,7 +67,7 @@
     public static final String ZKGROUP_SERVER_PUBLIC_PARAMS = "AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXTLfN0/vLt98KDPnxwAQL9j5V1jGOY8jQl6MLxEs56cwXN0dqCnImzVH3TZT1cJ8SW1BRX6qIVxEzjsSGx3yxF3suAilPMqGRp4ffyopjMD1JXiKR2RwLKzizUe5e8XyGOy9fplzhw3jVzTRyUZTRSZKkMLWcQ/gv0E4aONNqs4P+NameAZYOD12qRkxosQQP5uux6B2nRyZ7sAV54DgFyLiRcq1FvwKw2EPQdk4HDoePrO/RNUbyNddnM/mMgj4FW65xCoT1LmjrIjsv/Ggdlx46ueczhMgtBunx1/w8k8V+l8LVZ8gAT6wkU5J+DPQalQguMg12Jzug3q4TbdHiGCmD9EunCwOmsLuLJkz6EcSYXtrlDEnAM+hicw7iergYLLlMXpfTdGxJCWJmP4zqUFeTTmsmhsjGBt7NiEB/9pFFEB3pSbf4iiUukw63Eo8Aqnf4iwob6X1QviCWuc8t0LUlT9vALgh/f2DPVOOmR0RW6bgRvc7DSF20V/omg+YBw==";
     
     static {
-        LANGUAGES = new String[] { "uk", "mk", "ar", "ko", "da", "bn", "nb", "lt", "bs", "gu", "yue", "tr", "te", "fi", "ro", "hi", "ja", "bg", "kn", "km", "af", "et", "in", "sq", "zh_HK", "fr", "kk", "ms", "cs", "ca", "hu", "ml", "el", "ta", "pa", "th", "az", "ug", "nl", "sw", "it", "de", "vi", "ga", "zh_CN", "hr", "gl", "tl", "lv", "my", "ru", "ky", "es", "sk", "sv", "fa", "sr", "ka", "eu", "sl", "ur", "pl", "pt", "mr", "iw", "zh_TW", "pt_BR", "en" };
+        LANGUAGES = new String[] { "es", "gu", "bn", "sv", "ca", "pt_BR", "pt", "bs", "zh_HK", "fa", "da", "ml", "sq", "tr", "ja", "zh_CN", "az", "nl", "el", "et", "pa", "sk", "ar", "sr", "kk", "my", "nb", "vi", "pl", "ro", "lt", "ru", "ky", "uk", "it", "ko", "cs", "fr", "mk", "ug", "lv", "iw", "hi", "ga", "fi", "hr", "ka", "yue", "hu", "af", "th", "km", "tl", "zh_TW", "de", "eu", "sl", "kn", "bg", "ms", "ta", "te", "mr", "gl", "sw", "ur", "in", "en" };
         LIBSIGNAL_NET_ENV = Network$Environment.PRODUCTION;
         final String s = "104.18.37.148";
         final String s2 = "172.64.150.108";
--- x/classes4-enjarify/org/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections.class.java	2024-05-19 00:28:06.651492185 +0200
+++ y/classes4-enjarify/org/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections.class.java	2024-05-19 00:28:07.243497268 +0200
@@ -5,12 +5,18 @@
 package org.thoughtcrime.securesms.backup.v2.ui.restore;
 
 import org.thoughtcrime.securesms.devicetransfer.moreoptions.MoreTransferOrRestoreOptionsMode;
+import org.thoughtcrime.securesms.SignupDirections;
+import androidx.navigation.NavDirections;
 
 public class RestoreFromBackupFragmentDirections
 {
     private RestoreFromBackupFragmentDirections() {
     }
     
+    public static NavDirections actionRestartToWelcomeFragment() {
+        return SignupDirections.actionRestartToWelcomeFragment();
+    }
+    
     public static RestoreFromBackupFragmentDirections$ActionRestoreFromBacakupFragmentToMoreOptions actionRestoreFromBacakupFragmentToMoreOptions(final MoreTransferOrRestoreOptionsMode moreTransferOrRestoreOptionsMode) {
         return new RestoreFromBackupFragmentDirections$ActionRestoreFromBacakupFragmentToMoreOptions(moreTransferOrRestoreOptionsMode, null);
     }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragmentDirections.class.java	2024-05-19 00:28:07.871502659 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragmentDirections.class.java	2024-05-19 00:28:08.539508393 +0200
@@ -4,6 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
+import org.thoughtcrime.securesms.SignupDirections;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -15,4 +16,8 @@
     public static NavDirections actionNewDeviceTransferCompleteToEnterPhoneNumberFragment() {
         return (NavDirections)new ActionOnlyNavDirections(2131362048);
     }
+    
+    public static NavDirections actionRestartToWelcomeFragment() {
+        return SignupDirections.actionRestartToWelcomeFragment();
+    }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragmentDirections.class.java	2024-05-19 00:28:09.063512892 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragmentDirections.class.java	2024-05-19 00:28:09.623517699 +0200
@@ -4,6 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
+import org.thoughtcrime.securesms.SignupDirections;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -19,4 +20,8 @@
     public static NavDirections actionNewDeviceTransferToNewDeviceTransferInstructions() {
         return (NavDirections)new ActionOnlyNavDirections(2131362050);
     }
+    
+    public static NavDirections actionRestartToWelcomeFragment() {
+        return SignupDirections.actionRestartToWelcomeFragment();
+    }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragmentDirections.class.java	2024-05-19 00:28:10.243523022 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragmentDirections.class.java	2024-05-19 00:28:10.835528104 +0200
@@ -4,6 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
+import org.thoughtcrime.securesms.SignupDirections;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -15,4 +16,8 @@
     public static NavDirections actionDeviceTransferSetup() {
         return (NavDirections)new ActionOnlyNavDirections(2131361952);
     }
+    
+    public static NavDirections actionRestartToWelcomeFragment() {
+        return SignupDirections.actionRestartToWelcomeFragment();
+    }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragmentDirections.class.java	2024-05-19 00:28:11.347532499 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragmentDirections.class.java	2024-05-19 00:28:11.915537376 +0200
@@ -4,6 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
+import org.thoughtcrime.securesms.SignupDirections;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -19,4 +20,8 @@
     public static NavDirections actionNewDeviceTransfer() {
         return (NavDirections)new ActionOnlyNavDirections(2131362051);
     }
+    
+    public static NavDirections actionRestartToWelcomeFragment() {
+        return SignupDirections.actionRestartToWelcomeFragment();
+    }
 }

Variant 2:

--- x/classes4-enjarify/org/thoughtcrime/securesms/BuildConfig.class.java	2024-05-19 00:16:05.569301994 +0200
+++ y/classes4-enjarify/org/thoughtcrime/securesms/BuildConfig.class.java	2024-05-19 00:16:06.333308553 +0200
@@ -67,7 +67,7 @@
     public static final String ZKGROUP_SERVER_PUBLIC_PARAMS = "AMhf5ywVwITZMsff/eCyudZx9JDmkkkbV6PInzG4p8x3VqVJSFiMvnvlEKWuRob/1eaIetR31IYeAbm0NdOuHH8Qi+Rexi1wLlpzIo1gstHWBfZzy1+qHRV5A4TqPp15YzBPm0WSggW6PbSn+F4lf57VCnHF7p8SvzAA2ZZJPYJURt8X7bbg+H3i+PEjH9DXItNEqs2sNcug37xZQDLm7X36nOoGPs54XsEGzPdEV+itQNGUFEjY6X9Uv+Acuks7NpyGvCoKxGwgKgE5XyJ+nNKlyHHOLb6N1NuHyBrZrgtY/JYJHRooo5CEqYKBqdFnmbTVGEkCvJKxLnjwKWf+fEPoWeQFj5ObDjcKMZf2Jm2Ae69x+ikU5gBXsRmoF94GXTLfN0/vLt98KDPnxwAQL9j5V1jGOY8jQl6MLxEs56cwXN0dqCnImzVH3TZT1cJ8SW1BRX6qIVxEzjsSGx3yxF3suAilPMqGRp4ffyopjMD1JXiKR2RwLKzizUe5e8XyGOy9fplzhw3jVzTRyUZTRSZKkMLWcQ/gv0E4aONNqs4P+NameAZYOD12qRkxosQQP5uux6B2nRyZ7sAV54DgFyLiRcq1FvwKw2EPQdk4HDoePrO/RNUbyNddnM/mMgj4FW65xCoT1LmjrIjsv/Ggdlx46ueczhMgtBunx1/w8k8V+l8LVZ8gAT6wkU5J+DPQalQguMg12Jzug3q4TbdHiGCmD9EunCwOmsLuLJkz6EcSYXtrlDEnAM+hicw7iergYLLlMXpfTdGxJCWJmP4zqUFeTTmsmhsjGBt7NiEB/9pFFEB3pSbf4iiUukw63Eo8Aqnf4iwob6X1QviCWuc8t0LUlT9vALgh/f2DPVOOmR0RW6bgRvc7DSF20V/omg+YBw==";
     
     static {
-        LANGUAGES = new String[] { "my", "cs", "ur", "eu", "sl", "zh_TW", "es", "ga", "uk", "zh_HK", "bn", "gu", "ko", "it", "km", "fi", "ta", "tr", "gl", "hi", "pa", "iw", "tl", "lv", "pt_BR", "az", "sq", "ms", "ug", "pt", "ka", "nb", "fr", "mr", "kk", "hu", "el", "af", "lt", "de", "ru", "et", "bs", "mk", "ar", "ca", "ro", "sw", "sk", "zh_CN", "sr", "yue", "fa", "in", "th", "te", "kn", "ml", "vi", "nl", "sv", "ky", "hr", "pl", "bg", "da", "ja", "en" };
+        LANGUAGES = new String[] { "es", "gu", "bn", "sv", "ca", "pt_BR", "pt", "bs", "zh_HK", "fa", "da", "ml", "sq", "tr", "ja", "zh_CN", "az", "nl", "el", "et", "pa", "sk", "ar", "sr", "kk", "my", "nb", "vi", "pl", "ro", "lt", "ru", "ky", "uk", "it", "ko", "cs", "fr", "mk", "ug", "lv", "iw", "hi", "ga", "fi", "hr", "ka", "yue", "hu", "af", "th", "km", "tl", "zh_TW", "de", "eu", "sl", "kn", "bg", "ms", "ta", "te", "mr", "gl", "sw", "ur", "in", "en" };
         LIBSIGNAL_NET_ENV = Network$Environment.PRODUCTION;
         final String s = "104.18.37.148";
         final String s2 = "172.64.150.108";
--- x/classes4-enjarify/org/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections.class.java	2024-05-19 00:16:06.833312845 +0200
+++ y/classes4-enjarify/org/thoughtcrime/securesms/backup/v2/ui/restore/RestoreFromBackupFragmentDirections.class.java	2024-05-19 00:16:07.349317275 +0200
@@ -5,7 +5,7 @@
 package org.thoughtcrime.securesms.backup.v2.ui.restore;
 
 import org.thoughtcrime.securesms.devicetransfer.moreoptions.MoreTransferOrRestoreOptionsMode;
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class RestoreFromBackupFragmentDirections
@@ -13,8 +13,8 @@
     private RestoreFromBackupFragmentDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
     
     public static RestoreFromBackupFragmentDirections$ActionRestoreFromBacakupFragmentToMoreOptions actionRestoreFromBacakupFragmentToMoreOptions(final MoreTransferOrRestoreOptionsMode moreTransferOrRestoreOptionsMode) {
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/moreoptions/MoreTransferOrRestoreOptionsSheetDirections.class.java	2024-05-19 00:16:07.813321258 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/moreoptions/MoreTransferOrRestoreOptionsSheetDirections.class.java	2024-05-19 00:16:08.305325482 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.moreoptions;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class MoreTransferOrRestoreOptionsSheetDirections
@@ -12,7 +12,7 @@
     private MoreTransferOrRestoreOptionsSheetDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragmentDirections.class.java	2024-05-19 00:16:08.861330255 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferCompleteFragmentDirections.class.java	2024-05-19 00:16:09.389334788 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -13,11 +13,11 @@
     private NewDeviceTransferCompleteFragmentDirections() {
     }
     
-    public static NavDirections actionNewDeviceTransferCompleteToEnterPhoneNumberFragment() {
-        return (NavDirections)new ActionOnlyNavDirections(2131362048);
+    public static NavDirections actionNewDeviceTransferCompleteToEnterPhoneNumberV2Fragment() {
+        return (NavDirections)new ActionOnlyNavDirections(2131362049);
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragmentDirections.class.java	2024-05-19 00:16:09.921339355 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferFragmentDirections.class.java	2024-05-19 00:16:10.505344368 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -21,7 +21,7 @@
         return (NavDirections)new ActionOnlyNavDirections(2131362051);
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragmentDirections.class.java	2024-05-19 00:16:11.057349107 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferInstructionsFragmentDirections.class.java	2024-05-19 00:16:11.601353777 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -17,7 +17,7 @@
         return (NavDirections)new ActionOnlyNavDirections(2131361952);
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragmentDirections.class.java	2024-05-19 00:16:12.189358825 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/NewDeviceTransferSetupFragmentDirections.class.java	2024-05-19 00:16:12.725363426 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -21,7 +21,7 @@
         return (NavDirections)new ActionOnlyNavDirections(2131362052);
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragmentDirections.class.java	2024-05-19 00:16:13.257367993 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/devicetransfer/newdevice/TransferOrRestoreFragmentDirections.class.java	2024-05-19 00:16:13.769372389 +0200
@@ -5,7 +5,7 @@
 package org.thoughtcrime.securesms.devicetransfer.newdevice;
 
 import org.thoughtcrime.securesms.devicetransfer.moreoptions.MoreTransferOrRestoreOptionsMode;
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -22,8 +22,8 @@
         return (NavDirections)new ActionOnlyNavDirections(2131362053);
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
     
     public static TransferOrRestoreFragmentDirections$ActionTransferOrRestoreToMoreOptions actionTransferOrRestoreToMoreOptions(final MoreTransferOrRestoreOptionsMode moreTransferOrRestoreOptionsMode) {
--- x/classes5-enjarify/org/thoughtcrime/securesms/preferences/EditProxyFragmentDirections.class.java	2024-05-19 00:16:14.309377024 +0200
+++ y/classes5-enjarify/org/thoughtcrime/securesms/preferences/EditProxyFragmentDirections.class.java	2024-05-19 00:16:14.829381488 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.preferences;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class EditProxyFragmentDirections
@@ -12,7 +12,7 @@
     private EditProxyFragmentDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/AccountLockedFragmentDirections.class.java	2024-05-19 00:16:15.397386364 +0200
+++ y/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/AccountLockedFragmentDirections.class.java	2024-05-19 00:16:15.981391378 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.registration.fragments;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class AccountLockedFragmentDirections
@@ -12,7 +12,7 @@
     private AccountLockedFragmentDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/CaptchaFragmentDirections.class.java	2024-05-19 00:16:16.581396529 +0200
+++ y/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/CaptchaFragmentDirections.class.java	2024-05-19 00:16:17.229402091 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.registration.fragments;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class CaptchaFragmentDirections
@@ -12,7 +12,7 @@
     private CaptchaFragmentDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/ChooseBackupFragmentDirections.class.java	2024-05-19 00:16:17.857407483 +0200
+++ y/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/ChooseBackupFragmentDirections.class.java	2024-05-19 00:16:18.545413389 +0200
@@ -5,7 +5,7 @@
 package org.thoughtcrime.securesms.registration.fragments;
 
 import androidx.navigation.ActionOnlyNavDirections;
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class ChooseBackupFragmentDirections
@@ -13,8 +13,8 @@
     private ChooseBackupFragmentDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
     
     public static ChooseBackupFragmentDirections$ActionRestore actionRestore() {
--- x/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/CountryPickerFragmentDirections.class.java	2024-05-19 00:16:19.137418470 +0200
+++ y/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/CountryPickerFragmentDirections.class.java	2024-05-19 00:16:19.753423759 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.registration.fragments;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class CountryPickerFragmentDirections
@@ -12,7 +12,7 @@
     private CountryPickerFragmentDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/RegistrationCompleteFragmentDirections.class.java	2024-05-19 00:16:20.373429082 +0200
+++ y/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/RegistrationCompleteFragmentDirections.class.java	2024-05-19 00:16:20.929433855 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.registration.fragments;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.NavDirections;
 
 public class RegistrationCompleteFragmentDirections
@@ -12,7 +12,7 @@
     private RegistrationCompleteFragmentDirections() {
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
 }
--- x/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragmentDirections.class.java	2024-05-19 00:16:21.565439314 +0200
+++ y/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/RegistrationLockFragmentDirections.class.java	2024-05-19 00:16:22.201444774 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.registration.fragments;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -17,8 +17,8 @@
         return (NavDirections)new ActionOnlyNavDirections(2131361856);
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
     
     public static NavDirections actionSuccessfulRegistration() {
--- x/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragmentDirections.class.java	2024-05-19 00:16:22.773449685 +0200
+++ y/classes6-enjarify/org/thoughtcrime/securesms/registration/fragments/RestoreBackupFragmentDirections.class.java	2024-05-19 00:16:23.393455007 +0200
@@ -4,7 +4,7 @@
 
 package org.thoughtcrime.securesms.registration.fragments;
 
-import org.thoughtcrime.securesms.SignupDirections;
+import org.thoughtcrime.securesms.SignupV2Directions;
 import androidx.navigation.ActionOnlyNavDirections;
 import androidx.navigation.NavDirections;
 
@@ -21,8 +21,8 @@
         return (NavDirections)new ActionOnlyNavDirections(2131362054);
     }
     
-    public static NavDirections actionRestartToWelcomeFragment() {
-        return SignupDirections.actionRestartToWelcomeFragment();
+    public static NavDirections actionRestartToWelcomeV2Fragment() {
+        return SignupV2Directions.actionRestartToWelcomeV2Fragment();
     }
     
     public static NavDirections actionSkip() {

@nicholas-signal
Copy link
Contributor

Hello,

Thanks for the detailed analysis!

  1. The language list should be easy enough to include sort; good catch.
  2. These are methods are generated from XML using the AndroidX Navigation component. Specifically, this navigation graph is under active development and I am relying on some undefined behavior (re-using a resource ID for a navigation destination) to keep both the old & new graphs both working. Hopefully this sufficiently explains the differences and similarities of actionRestartToWelcomeFragment and actionRestartToWelcomeV2Fragment
  3. Upgrading our toolchain, including AGP, is something we are focusing on for v7.9

Copy link

stale bot commented Jul 20, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Jul 20, 2024
@greyson-signal
Copy link
Contributor

greyson-signal commented Jul 22, 2024

Huh, I'm surprised this wasn't caught on our end either! We have a nightly job that builds three APK's from scratch, signs one, and does cross comparisons between all of them as a means to wean out and non-determinism... I wonder if the system just tended to always give the files in the same order.

Thank you very much for telling us about the AGP 8.1 fixes! I will try to remove some of the files we've been ignoring and check to make sure things still verify. Since Nicholas posted we have indeed fixed the language bug and upgraded all the way to AGP 8.4, so hopefully that's all resolved. Not sure about Navigation bug, but it's not causing issues in the setup I described above, so curious if you're still hitting it.

Also, I was reading up on your work and found https://github.com/obfusk/apksigcopier -- a very cool project! When I get some time I'll see if I can get our app to verify using that tool. Seems like a super clever way to do it. Hopefully our move to split apk's doesn't complicate it, but we'll see 🤞

@obfusk
Copy link
Author

obfusk commented Jul 29, 2024

I will try verifying the website APK again sometime soon and report back.

By promising identical results are always generated from a given source, this allows multiple third parties to come to a consensus on a “correct” result [...]

Split APKs certainly complicate Reproducible Builds. Having only device-specific APKs instead of a single reference APK (or a handful of reference APKs when using split ABI) makes consensus on a "correct" result much harder, if not impossible, as "correct" is no longer universal but device-specific.

FYI: I cannot easily work on supporting/testing signature copying for split APKs as I have no Android devices with the play store installed to test with. Help would be appreciated :)

@obfusk
Copy link
Author

obfusk commented Aug 4, 2024

I will try verifying the website APK again sometime soon and report back.

Sadly, I can't reproduce it. Though the results I get are different from before.

I've tried both github actions with the Dockerfile and instructions from this repo (as before):

I get differences in classes.dex, classes3.dex, classes4.dex, classes5.dex, classes6.dex (as well as the .prof and .profm but that is expected with differences in .dex).

Except for classes6.dex they all differ only in the pg-map-id:

@@ -1,5 +1,5 @@
-00000000: 6465 780a 3033 3500 7ac7 4fe4 18f2 c5e7  dex.035.z.O.....
-00000010: 7795 ca9c 5e3c 03c2 9383 0243 a092 dddd  w...^<.....C....
+00000000: 6465 780a 3033 3500 e2c5 1d0c 9e2c 0021  dex.035......,.!
+00000010: 0475 e30c dbae 870d e95c 8ebc 3a5f dbea  .u.......\..:_..
 00000020: 04b4 a400 7000 0000 7856 3412 0000 0000  ....p...xV4.....
 00000030: 0000 0000 34b3 a400 1f25 0100 7000 0000  ....4....%..p...
 00000040: 3b2e 0000 ec94 0400 533f 0000 d84d 0500  ;.......S?...M..
@@ -582377,7 +582377,7 @@
 008e2e80: 2268 6173 2d63 6865 636b 7375 6d73 223a  "has-checksums":
 008e2e90: 6661 6c73 652c 226d 696e 2d61 7069 223a  false,"min-api":
 008e2ea0: 3231 2c22 7067 2d6d 6170 2d69 6422 3a22  21,"pg-map-id":"
-008e2eb0: 3565 3062 6331 3822 2c22 7238 2d6d 6f64  5e0bc18","r8-mod
+008e2eb0: 3932 3761 6333 3822 2c22 7238 2d6d 6f64  927ac38","r8-mod
 008e2ec0: 6522 3a22 6675 6c6c 222c 2276 6572 7369  e":"full","versi
 008e2ed0: 6f6e 223a 2238 2e34 2e32 3622 7d00 01c2  on":"8.4.26"}...
 008e2ee0: a000 01e2 808b 0001 e280 a600 02ed acbf  ................

classes6.dex has code differences too (only that small one):

@@ -142044,7 +142044,7 @@
         0x0000 - 0x0004 reg=0 this Lorg/thoughtcrime/securesms/registration/fragments/CountryPickerFragmentDirections; 
 
     #1              : (in Lorg/thoughtcrime/securesms/registration/fragments/CountryPickerFragmentDirections;)
-      name          : 'actionPopAppSettingsChangeNumber'
+      name          : 'actionRestartToWelcomeFragment'
       type          : '()Landroidx/navigation/NavDirections;'
       access        : 0x0009 (PUBLIC STATIC)
       code          -
@@ -142052,8 +142052,8 @@
       ins           : 0
       outs          : 0
       insns size    : 5 16-bit code units
-| org.thoughtcrime.securesms.registration.fragments.CountryPickerFragmentDirections.actionPopAppSettingsChangeNumber:()Landroidx/navigation/NavDirections;
-|: invoke-static {}, Lorg/thoughtcrime/securesms/AppSettingsChangeNumberDirections;.actionPopAppSettingsChangeNumber:()Landroidx/navigation/NavDirections;
+| org.thoughtcrime.securesms.registration.fragments.CountryPickerFragmentDirections.actionRestartToWelcomeFragment:()Landroidx/navigation/NavDirections;
+|: invoke-static {}, Lorg/thoughtcrime/securesms/SignupDirections;.actionRestartToWelcomeFragment:()Landroidx/navigation/NavDirections;
 |: move-result-object v0
 |: return-object v0
       catches       : (none)

As well as using rbtlog (Reproducible Builds Transparency Log for Android APKs):

The build environment used should be very close to identical to the docker container from this repo. It's also an ubuntu:jammy docker container -- with the same SDK versions etc. Just a more recent one and without the apt config changes.

But this has many of these odd small differences in constant values (and nothing else) in classes4.dex, classes5.dex, classes6.dex compared to the rebuild using the container from this repo, which is quite odd.

@@ -65320,7 +65320,7 @@
 |: invoke-interface/range {v19}, Landroidx/compose/runtime/Composer;.endReplaceableGroup:()V
 |: move-object v12, v3
 |: check-cast v12, Landroidx/compose/runtime/MutableState;
-|: const v3, #float 9.60821e+37 // #7e90917e
+|: const v3, #float -1.98074e-22 // #9b6f74e6
 |: invoke-interface {v11, v3}, Landroidx/compose/runtime/Composer;.startReplaceableGroup:(I)V
 |: invoke-interface {v11, v12}, Landroidx/compose/runtime/Composer;.changed:(Ljava/lang/Object;)Z
 |: move-result v3

@stale stale bot removed the wontfix label Aug 4, 2024
@obfusk
Copy link
Author

obfusk commented Aug 5, 2024

Looks like all those differences in constant values are calls to startReplaceableGroup() with different keys between the two builds. That suggests nondeterminism in the compose compiler 🙃

Copy link

stale bot commented Oct 5, 2024

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the wontfix label Oct 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Development

No branches or pull requests

3 participants