diff --git a/obelisk/dep/tahoe-chk/default.nix b/obelisk/dep/tahoe-chk/default.nix
new file mode 100644
index 0000000000000000000000000000000000000000..2b4d4ab11148e306f1f2f6acd94168ec417507e7
--- /dev/null
+++ b/obelisk/dep/tahoe-chk/default.nix
@@ -0,0 +1,2 @@
+# DO NOT HAND-EDIT THIS FILE
+import (import ./thunk.nix)
\ No newline at end of file
diff --git a/obelisk/dep/tahoe-chk/git.json b/obelisk/dep/tahoe-chk/git.json
new file mode 100644
index 0000000000000000000000000000000000000000..e03624e1ea06d56bdbf8b3a1a75fabe7503f37c9
--- /dev/null
+++ b/obelisk/dep/tahoe-chk/git.json
@@ -0,0 +1,8 @@
+{
+  "url": "https://whetstone.private.storage/privatestorage/tahoe-chk",
+  "rev": "f72194fcfe7e97fe53233145ae90512a857735c4",
+  "sha256": "094j7a0ybandwspmix36rq1hizpfj0xmja0sbwrxwvmbacc14zih",
+  "private": false,
+  "fetchSubmodules": false,
+  "branch": "chk-decoding"
+}
diff --git a/obelisk/dep/tahoe-chk/thunk.nix b/obelisk/dep/tahoe-chk/thunk.nix
new file mode 100644
index 0000000000000000000000000000000000000000..3e23b43a8138c810ce3a3cd75b68a13f7e7277b1
--- /dev/null
+++ b/obelisk/dep/tahoe-chk/thunk.nix
@@ -0,0 +1,17 @@
+# DO NOT HAND-EDIT THIS FILE
+let fetch = {url, rev, branch ? null, sha256 ? null, fetchSubmodules ? false, private ? false, ...}:
+  let realUrl = let firstChar = builtins.substring 0 1 url; in
+    if firstChar == "/" then /. + url
+    else if firstChar == "." then ./. + url
+    else url;
+  in if !fetchSubmodules && private then builtins.fetchGit {
+    url = realUrl; inherit rev;
+    ${if branch == null then null else "ref"} = branch;
+  } else (import (builtins.fetchTarball {
+  url = "https://github.com/NixOS/nixpkgs/archive/3aad50c30c826430b0270fcf8264c8c41b005403.tar.gz";
+  sha256 = "0xwqsf08sywd23x0xvw4c4ghq0l28w2ki22h0bdn766i16z9q2gr";
+}) {}).fetchgit {
+    url = realUrl; inherit rev sha256;
+  };
+  json = builtins.fromJSON (builtins.readFile ./git.json);
+in fetch json
\ No newline at end of file
diff --git a/obelisk/frontend/frontend.cabal b/obelisk/frontend/frontend.cabal
index fa2e9c728efab90e692d1ebfb9de8f509eafd1cc..42a6fdd89cf1f614b34d1a078526178985402585 100644
--- a/obelisk/frontend/frontend.cabal
+++ b/obelisk/frontend/frontend.cabal
@@ -14,6 +14,7 @@ library
                , obelisk-executable-config-lookup
                , obelisk-generated-static
                , text
+               , tahoe-chk
   if os(android)
     build-depends: android-activity
   else
diff --git a/obelisk/haskell-overrides.nix b/obelisk/haskell-overrides.nix
index 3066de306820895a615c9cd91fad6ca4bd838717..5b2d1a2618a093f20b1f718b03015f68ab98e40d 100644
--- a/obelisk/haskell-overrides.nix
+++ b/obelisk/haskell-overrides.nix
@@ -2,4 +2,18 @@
 self: super:
 with pkgs.haskell.lib; {
   # Override elements of the Haskell package set here.
+
+  # Here, we get the tahoe-chk package from the chk.hs thunk, and use
+  # callCabal2nix to get a nix derivation to build it.  See the comment in
+  # ./nixpkgs-overlay.nix for a description of how to interact with nix
+  # thunks.
+  tahoe-chk = dontCheck (self.callCabal2nix "tahoe-chk" (nix-thunk.thunkSource ./dep/tahoe-chk) {});
+
+  # We also ended up needing an override of the base32 library, which we
+  # obtain from Hackage.
+  base32 = self.callHackageDirect {
+    pkg = "base32";
+    ver = "0.2.1.0";
+    sha256 = "04glpmwp50qi29h8cb5j0w1rz0ww30nw4xgj2a3l7zh1gprhwj89";
+  } {};
 }
diff --git a/obelisk/nixpkgs-overlay.nix b/obelisk/nixpkgs-overlay.nix
index 1cc0c943fb2edf42cc1c9ac9b762af0577e4a6f3..5541c153db4728c354e41536aabf9c1e055a78dc 100644
--- a/obelisk/nixpkgs-overlay.nix
+++ b/obelisk/nixpkgs-overlay.nix
@@ -3,6 +3,33 @@
 let
   # Some helpers for defining our overloads go up here.
 
+  # Get a newer version of nixpkgs because the Botan2 expression in the
+  # reflex-platform-pinned nixpkgs has trouble building the version of
+  # Botan2 source that our changes are based on.
+  nixpkgs-new = import (nix-thunk.thunkSource ./dep/nixpkgs-22.11) {
+    # XXX Is this the right system?
+    system = self.stdenv.buildPlatform.system;
+  };
+
+  # Given a package set which may have some cross-compilation configuration,
+  # return the equivalently configured versiopn of another package set.  This
+  # function makes no attempt to be completely general (that would be neat!)
+  # but instead only handles exactly the cases required for this app to do
+  # native x86_64-linux and Android cross builds.
+  mirrorPkgset = pkgs: pkgs-new:
+    let
+      host = pkgs.stdenv.hostPlatform;
+    in
+      if host.isAndroid
+      then
+        if host.isAarch32
+        then pkgs-new.pkgsCross.armv7a-android-prebuilt
+        else pkgs-new.pkgsCross.aarch64-android-prebuilt
+      else
+        if host.isLinux && host.isx86_64
+        then pkgs-new
+        else throw "PrivateStorageMobile unsupported host platform: ${host.system}";
+
   # Customize the Botan2 build to be minimal and to compile successfully when
   # the host platform is Android.
   #
@@ -103,19 +130,10 @@ in rec {
   # changes.
   botan2 =
     let
-      # Get a newer version of nixpkgs because the Botan2 expression in the
-      # reflex-platform-pinned nixpkgs has trouble building the version of
-      # Botan2 source that our changes are based on.
-      nixpkgs-new = import (nix-thunk.thunkSource ./dep/nixpkgs-22.11) {
-        system = "x86_64-linux";
-      };
-
-      # XXX Pick the cross-compiled Android package set so the correct build
-      # tools will be supplied.  Unfortunately, this also means
-      # `nixpkgs.botan2` is *always* the cross-compiled Android build.  The
-      # native build for all platforms is clobbered.  I'm not sure how to
-      # avoid this.
-      pkgs = nixpkgs-new.pkgsCross.aarch64-android-prebuilt;
+      # Pick a version of the new nixpkgs that matches the configuration we're
+      # supposed to be using, as taken from the fixed point package set
+      # (self).
+      pkgs = mirrorPkgset self nixpkgs-new;
     in
       # Use the selected package set to build our customized Botan2.
       pkgs.callPackage customizedBotan2 { };