diff --git a/Makefile b/Makefile
index 8e59d3126d0c93a8958ffaeda27130e100b1fc5b..f1955bd0c974351c212a82888947bf58774343fa 100644
--- a/Makefile
+++ b/Makefile
@@ -20,7 +20,7 @@ update_release:
 	GOFLAGS="" go get gitlab.com/xx_network/primitives@release
 	GOFLAGS="" go get gitlab.com/elixxir/primitives@release
 	GOFLAGS="" go get gitlab.com/xx_network/crypto@release
-	GOFLAGS="" go get gitlab.com/elixxir/crypto@singleUseMultiPartRequest
+	GOFLAGS="" go get gitlab.com/elixxir/crypto@release
 	GOFLAGS="" go get gitlab.com/xx_network/comms@release
 	GOFLAGS="" go get gitlab.com/elixxir/comms@release
 	GOFLAGS="" go get gitlab.com/elixxir/ekv@master
diff --git a/README.md b/README.md
index 62b1ed0de9a3a23929243db3299027af71793ee2..85caa9719203f12bf8bfbcb7d9e22b02cf37102f 100644
--- a/README.md
+++ b/README.md
@@ -4,12 +4,12 @@
 [![coverage report](https://gitlab.com/elixxir/client/badges/master/coverage.svg)](https://gitlab.com/elixxir/client/commits/master)
 
 
-The client is a library and related command-line tool 
+The client is a library and related command-line tool
 that facilitates making full-featured xx clients for all platforms. It interfaces with the cMix system, enabling access
 to all xx network messaging features, including end-to-end encryption and metadata protection.
 
 This repository contains everything necessary to implement all of the
-xx network messaging features. It also contains features to extend the base 
+xx network messaging features. It also contains features to extend the base
 messaging protocols.
 
 The command-line tool accompanying the client library can be built for any platform supported by
@@ -27,7 +27,7 @@ The client is open-source software released under the simplified BSD License.
 ## Command Line Usage
 
 The command-line tool is intended for testing xx network functionality and not
-for regular user use. 
+for regular user use.
 
 These instructions assume that you have [Go 1.17.X installed](https://go.dev/doc/install), and GCC installed for Cgo (such as `build-essential` on Debian or Ubuntu).
 
@@ -51,12 +51,26 @@ GOOS=darwin GOARCH=amd64 CGO_ENABLED=0 go build -ldflags '-w -s' -o release/clie
 
 #### Fetching an NDF
 
-All actions performed with the client require a current [NDF](https://xxdk-dev.xx.network/technical-glossary#network-definition-file-ndf). The NDF is downloadable from the command line or [via an access point](https://xxdk-dev.xx.network/quick-reference#func-downloadandverifysignedndfwithurl) in the Client API.
+All actions performed with the client require a
+current [NDF](https://xxdk-dev.xx.network/technical-glossary#network-definition-file-ndf). The NDF is downloadable from
+the command line
+or [via an access point](https://xxdk-dev.xx.network/quick-reference#func-downloadandverifysignedndfwithurl) in the
+Client API.
 
-Use the `getndf` command to fetch the NDF via the command  line. `getndf` enables command-line users to poll the NDF from a network gateway without any pre-established client connection: 
+Use the `getndf` command to fetch the NDF via the command line. `getndf` enables command-line users to poll the NDF from
+a network gateway without any pre-established client connection.
+
+First, you'll want to download an SSL certificate:
+
+```
+// Assumes you are running a gateway locally
+openssl s_client -showcerts -connect localhost:8440 < /dev/null 2>&1 | openssl x509 -outform PEM > certfile.pem
+```
+
+Now you can fetch the NDF:
 
 ```
-// Fetch NDF (example usage for Gateways, assumes you are running a gateway locally)
+// Example usage for Gateways, assumes you are running a gateway locally
 $ go run main.go getndf --gwhost localhost:8440 --cert certfile.pem | jq . >ndf.json
 ```
 
@@ -83,10 +97,16 @@ Sample content of `ndf.json`:
 	  .....
 ```
 
-#### Sending safe messages between 2 users
+#### Sending Safe Messages Between Two (2) Users
+
+**Note:** For information on receiving messages and troubleshooting authenticated channel requests,
+see [Receiving Messages](#receiving-messages)
+and [Confirming authenticated channel requests](#confirming-authenticated-channel-requests).
 
 To send messages with end-to-end encryption, you must first establish a connection
-or [authenticated channel](https://xxdk-dev.xx.network/technical-glossary#authenticated-channel) with the other user:
+or [authenticated channel](https://xxdk-dev.xx.network/technical-glossary#authenticated-channel) with the other user.
+See below for example commands for sending or confirming authenticated channel requests, as well as for sending E2E
+messages:
 
 ```
 # Get user contact jsons for each client
@@ -102,9 +122,9 @@ Message received:
 Sending to Qm40C5hRUm7uhp5aATVWhSL6Mt+Z4JVBQrsEDvMORh4D:
 Received 1
 
-# Alternatively, to accept an authenticated channel request implicitly
-# (should be within the timeout window of requesting client, or the request will need to be resent):
-$ client --password "password" --ndf ndf.json -l client.log -s session-directory --destfile user2-contact.json" --unsafe-channel-creation --waitTimeout 200
+# Accept/Confirm an authenticated channel request implicitly
+# (should be within the timeout window of requesting client, or the request will need to be re-sent):
+$ client --password "password" --ndf ndf.json -l client.log -s session-directory --destfile user2-contact.json --unsafe-channel-creation --waitTimeout 200
 Authentication channel request from: o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD
 Sending to o+QpswTmnsuZve/QRz0j0RYNWqjgx4R5pACfO00Pe0cD:
 Message received:
@@ -128,7 +148,7 @@ Received 0
 * `-s`: The storage directory for client session data.
 * `--writeContact`: Output the user's contact information to this file.
 * `--destfile` is used to specify the recipient. You can also use
-  `--destid b64:...` using the user's base64 id which is printed in the logs.
+  `--destid b64:...` using the user's base64 id, which is printed in the logs.
 * `--unsafe`: Send message without encryption (necessary whenever you have not
   already established an e2e channel).
 * `--unsafe-channel-creation` Auto-create and auto-accept channel requests.
@@ -136,12 +156,12 @@ Received 0
 
 Note that the client defaults to sending to itself when a destination is not supplied.
 This is why we've used the `--unsafe` flag when creating the user contact jsons.
-However, when sending between users it is dropped in exchange for `--unsafe-channel-creation`.
+However, when sending between users, it is dropped in exchange for `--unsafe-channel-creation`.
 
-For the authenticated channel creation to be considered "safe" the user should be prompted. You can do this
-on the command line by explicitly accepting the channel creation
-when sending a request with `--send-auth-request` and/or explicitly accepting a request with
-`--accept-channel`:
+For the authenticated channel creation to be considered "safe", the user should be prompted. You can do this by
+explicitly accepting the channel creation
+when sending a request with `--send-auth-request` (while excluding the `--unsafe-channel-creation` flag) or explicitly
+accepting a request with `--accept-channel`:
 
 ```
 $ client --password user-password --ndf ndf.json -l client.log -s session-directory --destfile user-contact.json --accept-channel
@@ -151,6 +171,61 @@ Message received:
 Received 1
 ```
 
+#### Receiving Messages
+
+There is no explicit command for receiving messages. Instead, the client will attempt to fetch pending messages on each
+run.
+
+You can use the `--receiveCount` flag to limit the number of messages the client waits for before a timeout occurs:
+
+```
+$ client --password <password> --ndf <NDF JSON file> -l client.log -s <session directory> --destfile <contact JSON file> --receiveCount <integer count>
+```
+
+#### Sending Authenticated Channel Requests
+
+See [Sending Safe Messages Between Two (2) Users](#sending-safe-messages-between-two-2-users)
+
+#### Confirming Authenticated Channel Requests
+
+Setting up an authenticated channel between clients is a back-and-forth process that happens in sequence. One client
+sends a request and waits for the other to accept it.
+
+See the previous section, [Sending safe messages between 2 users](#sending-safe-messages-between-2-users), for example
+commands showing how to set up an end-to-end connection between clients before sending messages.
+
+As with received messages, there is no command for checking for authenticated channel requests; you'll be notified of
+any pending requests whenever the client is run.
+
+```
+$ ./client.win64 --password password --ndf ndf.json -l client.log -s session-directory --destfile user-contact8.json --waitTimeout 120 -m "Hi User 7, from User 8 with E2E Encryption"
+Authentication channel request from: 8zAWY69UUK/FkMBGY3ViR5MMfcp1GoKn6Y3c/64NYNYD
+Sending to yYAztmoCoAH2VIr00zPxnj/ZRvdiDdURjdDWys0KYI4D: Hi User 7, from User 8 with E2E Encryption
+Timed out!
+Received 0
+
+```
+
+##### Troubleshooting
+
+**`panic: Could not confirm authentication channel for ...`**
+
+Suppose the receiving client does not confirm the authentication channel before the requesting client reaches a
+timeout (default 120s). In that case, the request eventually terminates in
+a `panic: Could not confirm authentication channel for ...` error.
+
+Retrying the request should fix this. If necessary, you may increase the time the client waits to confirm the channel
+before timeout using the `--auth-timeout` flag (default 120s).
+
+This error will also occur with the receiving client if it received the request but failed to confirm it before the
+requesting client reached a timeout. In this case, the request needs to be resent while the other client reattempts to
+confirm the channel.
+
+**`panic: Received request not found`**
+
+You may also run into the `panic: Received request not found` error when attempting to confirm an authenticated channel
+request. This means your client has not received the request. If one has been sent, simply retrying should fix this.
+
 Full usage of client can be found with `client --help`:
 
 ```
@@ -221,9 +296,9 @@ Use "client [command] --help" for more information about a command.
 
 ## Library Overview
 
-The xx client is designed to be used as a go library (and by extension a 
-c library). 
- 
+The xx client is designed to be used as a go library (and by extension a
+c library).
+
 Support is also present for go mobile to build Android and iOS libraries. We
 bind all exported symbols from the bindings package for use on mobile
 platforms.
@@ -232,7 +307,8 @@ platforms.
 
 Clients need to perform the same actions *in the same order* as shown in
 `cmd/root.go`. Specifically, certain handlers need to be registered and
-set up before starting network threads. Additionally, you cannot perform certain actions until the network connection reaches a "healthy" state.
+set up before starting network threads. Additionally, you cannot perform certain actions until the network connection
+reaches a "healthy" state.
 
 See [main.go](https://git.xx.network/elixxir/xxdk-examples/-/blob/sample-messaging-app/sample-messaging-app/main.go) for relevant code listings on when and how to perform these actions.
 The [Getting Started](https://xxdk-dev.xx.network/getting-started) guide provides further detail.
@@ -340,7 +416,7 @@ parts of the roadmap that are intended for the client:
 * User Discovery - A bot that will allow the user to look for others on the
   network.
 * Notifications - An optional notifications system which uses firebase
-* Efficiency improvements - mechanisms for message pickup and network tracking 
+* Efficiency improvements - mechanisms for message pickup and network tracking
 * will evolve to allow tradeoffs and options for use
 
 We are also always looking at simplifying and improving the library interface.
diff --git a/api/version_vars.go b/api/version_vars.go
index b681e79ff65784d85fc3b31c182c6f51e09c8697..01757159c19fdb14130d00b25907d48091e56967 100644
--- a/api/version_vars.go
+++ b/api/version_vars.go
@@ -1,9 +1,9 @@
 // Code generated by go generate; DO NOT EDIT.
 // This file was generated by robots at
-// 2022-03-10 11:46:32.709433 -0600 CST m=+0.047217210
+// 2022-06-06 15:29:07.985136 -0500 CDT m=+0.025770522
 package api
 
-const GITVERSION = `0d927b59 Update deps`
+const GITVERSION = `3f73b1f6 re-add utils`
 const SEMVER = "4.1.0"
 const DEPENDENCIES = `module gitlab.com/elixxir/client
 
@@ -18,14 +18,15 @@ require (
 	github.com/spf13/cobra v1.1.1
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/viper v1.7.1
-	gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228
-	gitlab.com/elixxir/comms v0.0.4-0.20220308183624-c2183e687a03
-	gitlab.com/elixxir/crypto v0.0.7-0.20220309234716-1ba339865787
-	gitlab.com/elixxir/ekv v0.1.6
-	gitlab.com/elixxir/primitives v0.0.3-0.20220222212109-d412a6e46623
-	gitlab.com/xx_network/comms v0.0.4-0.20220223205228-7c4974139569
-	gitlab.com/xx_network/crypto v0.0.5-0.20220222212031-750f7e8a01f4
-	gitlab.com/xx_network/primitives v0.0.4-0.20220222211843-901fa4a2d72b
+	gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f
+	gitlab.com/elixxir/comms v0.0.4-0.20220603231314-e47e4af13326
+	gitlab.com/elixxir/crypto v0.0.7-0.20220606201132-c370d5039cea
+	gitlab.com/elixxir/ekv v0.1.7
+	gitlab.com/elixxir/primitives v0.0.3-0.20220606195757-40f7a589347f
+	gitlab.com/xx_network/comms v0.0.4-0.20220315161313-76acb14429ac
+	gitlab.com/xx_network/crypto v0.0.5-0.20220606200528-3f886fe49e81
+	gitlab.com/xx_network/primitives v0.0.4-0.20220324193139-b292d1ae6e7e
+	go.uber.org/ratelimit v0.2.0
 	golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed
 	golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2
 	google.golang.org/grpc v1.42.0
@@ -33,6 +34,7 @@ require (
 )
 
 require (
+	github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
 	github.com/badoux/checkmail v1.2.1 // indirect
 	github.com/elliotchance/orderedmap v1.4.0 // indirect
 	github.com/fsnotify/fsnotify v1.4.9 // indirect
@@ -56,6 +58,7 @@ require (
 	gitlab.com/xx_network/ring v0.0.3-0.20220222211904-da613960ad93 // indirect
 	golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac // indirect
 	golang.org/x/text v0.3.6 // indirect
+	golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect
 	google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1 // indirect
 	gopkg.in/ini.v1 v1.62.0 // indirect
 	gopkg.in/yaml.v2 v2.4.0 // indirect
diff --git a/backup/backup.go b/backup/backup.go
index 0e025f3fe28e116f77a19a81a873238db8c4b38a..46f5bf73019e9c26e66b2a780f141a5b788647a4 100644
--- a/backup/backup.go
+++ b/backup/backup.go
@@ -30,9 +30,6 @@ const (
 	errSavePassword      = "failed to save password: %+v"
 	errSaveKeySaltParams = "failed to save key, salt, and params: %+v"
 
-	// ResumeBackup
-	errLoadPassword = "backup not initialized: load user password failed: %+v"
-
 	// Backup.StopBackup
 	errDeletePassword = "failed to delete password: %+v"
 	errDeleteCrypto   = "failed to delete key, salt, and parameters: %+v"
@@ -106,12 +103,6 @@ func InitializeBackup(password string, updateBackupCb UpdateBackupFn,
 		rng:            rng,
 	}
 
-	// Save password to storage
-	err := savePassword(password, b.kv)
-	if err != nil {
-		return nil, errors.Errorf(errSavePassword, err)
-	}
-
 	// Derive key and get generated salt and parameters
 	rand := b.rng.GetStream()
 	salt, err := backup.MakeSalt(rand)
@@ -121,9 +112,9 @@ func InitializeBackup(password string, updateBackupCb UpdateBackupFn,
 	rand.Close()
 
 	params := backup.DefaultParams()
-	params.Memory = 256 * 1024 // 256 MiB
-	params.Threads = 4
-	params.Time = 100
+	params.Memory = 64 * 1024 // 64 MiB
+	params.Threads = 1
+	params.Time = 5
 	key := backup.DeriveKey(password, salt, params)
 
 	// Save key, salt, and parameters to storage
@@ -147,9 +138,9 @@ func InitializeBackup(password string, updateBackupCb UpdateBackupFn,
 func ResumeBackup(updateBackupCb UpdateBackupFn, container *messenger.Container,
 	e2e E2e, session Session, ud UserDiscovery, kv *versioned.KV,
 	rng *fastRNG.StreamGenerator) (*Backup, error) {
-	_, err := loadPassword(kv)
+	_, _, _, err := loadBackup(kv)
 	if err != nil {
-		return nil, errors.Errorf(errLoadPassword, err)
+		return nil, err
 	}
 
 	b := &Backup{
@@ -253,12 +244,7 @@ func (b *Backup) StopBackup() error {
 	defer b.mux.Unlock()
 	b.updateBackupCb = nil
 
-	err := deletePassword(b.kv)
-	if err != nil {
-		return errors.Errorf(errDeletePassword, err)
-	}
-
-	err = deleteBackup(b.kv)
+	err := deleteBackup(b.kv)
 	if err != nil {
 		return errors.Errorf(errDeleteCrypto, err)
 	}
diff --git a/backup/backup_test.go b/backup/backup_test.go
index eeda3711c16697038f98228e228ee04c441ea627..f61dc0a06b02adcaa3218c909a90dda6c90c3985 100644
--- a/backup/backup_test.go
+++ b/backup/backup_test.go
@@ -15,6 +15,7 @@ import (
 	"time"
 
 	"gitlab.com/elixxir/client/api/messenger"
+	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 
@@ -44,16 +45,6 @@ func Test_InitializeBackup(t *testing.T) {
 		t.Error("Timed out waiting for callback.")
 	}
 
-	// Check that the correct password is in storage
-	loadedPassword, err := loadPassword(b.kv)
-	if err != nil {
-		t.Errorf("Failed to load password: %+v", err)
-	}
-	if expectedPassword != loadedPassword {
-		t.Errorf("Loaded invalid key.\nexpected: %q\nreceived: %q",
-			expectedPassword, loadedPassword)
-	}
-
 	// Check that the key, salt, and params were saved to storage
 	key, salt, _, err := loadBackup(b.kv)
 	if err != nil {
@@ -121,17 +112,7 @@ func Test_ResumeBackup(t *testing.T) {
 		t.Errorf("ResumeBackup returned an error: %+v", err)
 	}
 
-	// Check that the correct password is in storage
-	loadedPassword, err := loadPassword(b.kv)
-	if err != nil {
-		t.Errorf("Failed to load password: %+v", err)
-	}
-	if expectedPassword != loadedPassword {
-		t.Errorf("Loaded invalid key.\nexpected: %q\nreceived: %q",
-			expectedPassword, loadedPassword)
-	}
-
-	// get key, salt, and parameters of resumed backup
+	// Get key, salt, and parameters of resumed backup
 	key2, salt2, _, err := loadBackup(b.kv)
 	if err != nil {
 		t.Errorf("Failed to load key, salt, and params from resumed "+
@@ -164,12 +145,12 @@ func Test_ResumeBackup(t *testing.T) {
 
 // Error path: Tests that ResumeBackup returns an error if no password is
 // present in storage.
-func Test_ResumeBackup_NoKeyError(t *testing.T) {
-	expectedErr := strings.Split(errLoadPassword, "%")[0]
-	kv := versioned.NewKV(ekv.MakeMemstore())
+func Test_resumeBackup_NoKeyError(t *testing.T) {
+	expectedErr := "object not found"
+	s := storage.InitTestingSession(t)
 	rngGen := fastRNG.NewStreamGenerator(1000, 10, csprng.NewSystemRNG)
 	_, err := ResumeBackup(nil, &messenger.Container{}, newMockE2e(t), newMockSession(t),
-		newMockUserDiscovery(), kv, rngGen)
+		newMockUserDiscovery(), s.GetKV(), rngGen)
 	if err == nil || !strings.Contains(err.Error(), expectedErr) {
 		t.Errorf("ResumeBackup did not return the expected error when no "+
 			"password is present.\nexpected: %s\nreceived: %+v", expectedErr, err)
@@ -181,13 +162,8 @@ func Test_ResumeBackup_NoKeyError(t *testing.T) {
 func TestBackup_TriggerBackup(t *testing.T) {
 	cbChan := make(chan []byte)
 	cb := func(encryptedBackup []byte) { cbChan <- encryptedBackup }
-	b := newTestBackup("MySuperSecurePassword", cb, t)
-
-	// get password
-	password, err := loadPassword(b.kv)
-	if err != nil {
-		t.Errorf("Failed to load password from storage: %+v", err)
-	}
+	password := "MySuperSecurePassword"
+	b := newTestBackup(password, cb, t)
 
 	collatedBackup := b.assembleBackup()
 
@@ -265,12 +241,6 @@ func TestBackup_StopBackup(t *testing.T) {
 	case <-time.After(10 * time.Millisecond):
 	}
 
-	// Make sure password is deleted
-	password, err := loadPassword(b.kv)
-	if err == nil || len(password) != 0 {
-		t.Errorf("Loaded password that should be deleted: %q", password)
-	}
-
 	// Make sure key, salt, and params are deleted
 	key, salt, p, err := loadBackup(b.kv)
 	if err == nil || len(key) != 0 || len(salt) != 0 || p != (backup.Params{}) {
diff --git a/backup/keyStorage.go b/backup/keyStorage.go
index 9a3f5cfe564abc782e4eb199ed7dbde254318fea..f0e11469e850f17363bee97f6c5cc9d47d377b97 100644
--- a/backup/keyStorage.go
+++ b/backup/keyStorage.go
@@ -9,6 +9,7 @@ package backup
 
 import (
 	"bytes"
+
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/backup"
@@ -100,29 +101,3 @@ func unmarshalBackup(buf []byte) (key, salt []byte, params backup.Params, err er
 
 	return
 }
-
-// savePassword saves the user's backup password to storage.
-func savePassword(password string, kv *versioned.KV) error {
-	obj := &versioned.Object{
-		Version:   passwordStorageVersion,
-		Timestamp: netTime.Now(),
-		Data:      []byte(password),
-	}
-
-	return kv.Set(passwordStorageKey, passwordStorageVersion, obj)
-}
-
-// loadPassword returns the user's backup password from storage.
-func loadPassword(kv *versioned.KV) (string, error) {
-	obj, err := kv.Get(passwordStorageKey, passwordStorageVersion)
-	if err != nil {
-		return "", err
-	}
-
-	return string(obj.Data), nil
-}
-
-// deletePassword deletes the user's backup password from storage.
-func deletePassword(kv *versioned.KV) error {
-	return kv.Delete(passwordStorageKey, passwordStorageVersion)
-}
diff --git a/backup/keyStorage_test.go b/backup/keyStorage_test.go
deleted file mode 100644
index 95e7a08915f4255dfc742277cf47b72a5e97b470..0000000000000000000000000000000000000000
--- a/backup/keyStorage_test.go
+++ /dev/null
@@ -1,95 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2020 xx network SEZC                                           //
-//                                                                            //
-// Use of this source code is governed by a license that can be found in the  //
-// LICENSE file                                                               //
-////////////////////////////////////////////////////////////////////////////////
-
-package backup
-
-import (
-	"testing"
-
-	"gitlab.com/elixxir/client/storage/versioned"
-	"gitlab.com/elixxir/ekv"
-	"gitlab.com/xx_network/primitives/netTime"
-)
-
-// Tests that savePassword saves the password to storage by loading it and
-// comparing it to the original.
-func Test_savePassword(t *testing.T) {
-	kv := versioned.NewKV(ekv.MakeMemstore())
-	expectedPassword := "MySuperSecurePassword"
-
-	// Save the password
-	err := savePassword(expectedPassword, kv)
-	if err != nil {
-		t.Errorf("savePassword returned an error: %+v", err)
-	}
-
-	// Attempt to load the password
-	obj, err := kv.Get(passwordStorageKey, passwordStorageVersion)
-	if err != nil {
-		t.Errorf("Failed to get password from storage: %+v", err)
-	}
-
-	// Check that the password matches the original
-	if expectedPassword != string(obj.Data) {
-		t.Errorf("Loaded password does not match original."+
-			"\nexpected: %q\nreceived: %q", expectedPassword, obj.Data)
-	}
-}
-
-// Tests that loadPassword restores the original password saved to stage and
-// compares it to the original.
-func Test_loadPassword(t *testing.T) {
-	kv := versioned.NewKV(ekv.MakeMemstore())
-	expectedPassword := "MySuperSecurePassword"
-
-	// Save the password
-	err := kv.Set(passwordStorageKey, passwordStorageVersion, &versioned.Object{
-		Version:   passwordStorageVersion,
-		Timestamp: netTime.Now(),
-		Data:      []byte(expectedPassword),
-	})
-	if err != nil {
-		t.Errorf("Failed to save password to storage: %+v", err)
-	}
-
-	// Attempt to load the password
-	loadedPassword, err := loadPassword(kv)
-	if err != nil {
-		t.Errorf("loadPassword returned an error: %+v", err)
-	}
-
-	// Check that the password matches the original
-	if expectedPassword != loadedPassword {
-		t.Errorf("Loaded password does not match original."+
-			"\nexpected: %q\nreceived: %q", expectedPassword, loadedPassword)
-	}
-}
-
-// Tests that deletePassword deletes the password from storage by trying to recover a
-// deleted password.
-func Test_deletePassword(t *testing.T) {
-	kv := versioned.NewKV(ekv.MakeMemstore())
-	expectedPassword := "MySuperSecurePassword"
-
-	// Save the password
-	err := savePassword(expectedPassword, kv)
-	if err != nil {
-		t.Errorf("Failed to save password to storage: %+v", err)
-	}
-
-	// Delete the password
-	err = deletePassword(kv)
-	if err != nil {
-		t.Errorf("deletePassword returned an error: %+v", err)
-	}
-
-	// Attempt to load the password
-	obj, err := loadPassword(kv)
-	if err == nil || obj != "" {
-		t.Errorf("Loaded object from storage when it should be deleted: %+v", obj)
-	}
-}
diff --git a/cmix/gateway/hostPool.go b/cmix/gateway/hostPool.go
index 224489af202afd203c1f917ce163b901deeade3d..52b29d45f1661cb025799d993e401e2dd9108cc3 100644
--- a/cmix/gateway/hostPool.go
+++ b/cmix/gateway/hostPool.go
@@ -271,7 +271,7 @@ func newHostPool(poolParams PoolParams, rng *fastRNG.StreamGenerator,
 	return result, nil
 }
 
-// initialize initializes the HostPool with a performant set of Hosts.
+// initialize the HostPool with a performant set of Hosts.
 func (h *HostPool) initialize(startIdx uint32) error {
 	// If HostPool is full, there is no need to initialize
 	if startIdx == h.poolParams.PoolSize {
diff --git a/cmix/nodes/register.go b/cmix/nodes/register.go
index 80c85547f333df28eda9cd21b14a98ab73623d71..000b5751501b8120c35f099f3a2db59257a8fb07 100644
--- a/cmix/nodes/register.go
+++ b/cmix/nodes/register.go
@@ -95,7 +95,7 @@ func registerNodes(r *registrar, s session, stop *stoppable.Single,
 
 			// Process the result
 			if err != nil {
-				jww.ERROR.Printf("Failed to register nodes: %s", err.Error())
+				jww.ERROR.Printf("Failed to register node: %s", err.Error())
 				// If we have not reached the attempt limit for this gateway,
 				// then send it back into the channel to retry
 				if numAttempts < maxAttempts {
diff --git a/cmix/nodes/request.go b/cmix/nodes/request.go
index b75f7801cbb53ed41843a92511a2e89cfafae91f..f41b6b88e2cf476c59f8b00344cfff7101537673 100644
--- a/cmix/nodes/request.go
+++ b/cmix/nodes/request.go
@@ -64,8 +64,8 @@ func requestKey(sender gateway.Sender, comms RegisterNodeCommsInterface,
 	result, err := sender.SendToAny(func(host *connect.Host) (interface{}, error) {
 		keyResponse, err2 := comms.SendRequestClientKeyMessage(host, signedKeyReq)
 		if err2 != nil {
-			return nil, errors.WithMessage(err2,
-				"Register: Failed requesting client key from gateway")
+			return nil, errors.WithMessagef(err2,
+				"Register: Failed requesting client key from gateway %s", gatewayID.String())
 		}
 		if keyResponse.Error != "" {
 			return nil, errors.WithMessage(err2,
diff --git a/go.mod b/go.mod
index 45cbd29359501276d3da18b7745794d21cdaaa8c..51d6cbb6177ab2785337edbe1864cbca8ac62689 100644
--- a/go.mod
+++ b/go.mod
@@ -12,12 +12,12 @@ require (
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/viper v1.7.1
 	gitlab.com/elixxir/bloomfilter v0.0.0-20211222005329-7d931ceead6f
-	gitlab.com/elixxir/comms v0.0.4-0.20220323190139-9ed75f3a8b2c
-	gitlab.com/elixxir/crypto v0.0.7-0.20220516144816-71049ce09e4b
+	gitlab.com/elixxir/comms v0.0.4-0.20220603231314-e47e4af13326
+	gitlab.com/elixxir/crypto v0.0.7-0.20220606201132-c370d5039cea
 	gitlab.com/elixxir/ekv v0.1.7
-	gitlab.com/elixxir/primitives v0.0.3-0.20220330212736-cce83b5f948f
+	gitlab.com/elixxir/primitives v0.0.3-0.20220606195757-40f7a589347f
 	gitlab.com/xx_network/comms v0.0.4-0.20220315161313-76acb14429ac
-	gitlab.com/xx_network/crypto v0.0.5-0.20220516143655-14f9153096ce
+	gitlab.com/xx_network/crypto v0.0.5-0.20220606200528-3f886fe49e81
 	gitlab.com/xx_network/primitives v0.0.4-0.20220324193139-b292d1ae6e7e
 	go.uber.org/ratelimit v0.2.0
 	golang.org/x/crypto v0.0.0-20220128200615-198e4374d7ed
diff --git a/go.sum b/go.sum
index c3aa45ee09d936b71b808d039ce87d0ea1bd0b5d..21c95717bd4b37fdda8fb56a405cf34685a293d7 100644
--- a/go.sum
+++ b/go.sum
@@ -397,6 +397,8 @@ gitlab.com/elixxir/comms v0.0.4-0.20220308183624-c2183e687a03 h1:4eNjO3wCyHgxpGe
 gitlab.com/elixxir/comms v0.0.4-0.20220308183624-c2183e687a03/go.mod h1:4yMdU+Jee5W9lqkZGHJAuipEhW7FloT0eyVEFUJza+E=
 gitlab.com/elixxir/comms v0.0.4-0.20220323190139-9ed75f3a8b2c h1:ajjTw08YjRjl3HvtBNGtoCWhOg8k8upqmTweH18wkC4=
 gitlab.com/elixxir/comms v0.0.4-0.20220323190139-9ed75f3a8b2c/go.mod h1:tlHSrtSliKWUxsck8z/Ql/VJkMdSONV2BeWaUAAXzgk=
+gitlab.com/elixxir/comms v0.0.4-0.20220603231314-e47e4af13326 h1:Zid8oNHtbOqF6ebrcGIccvIMabFNGh9dzY1b7mgIcF0=
+gitlab.com/elixxir/comms v0.0.4-0.20220603231314-e47e4af13326/go.mod h1:tlHSrtSliKWUxsck8z/Ql/VJkMdSONV2BeWaUAAXzgk=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
 gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
 gitlab.com/elixxir/crypto v0.0.7-0.20220222221347-95c7ae58da6b/go.mod h1:tD6XjtQh87T2nKZL5I/pYPck5M2wLpkZ1Oz7H/LqO10=
@@ -442,6 +444,10 @@ gitlab.com/elixxir/crypto v0.0.7-0.20220513133141-46faee2d8fca h1:0EINaZCe/0dPbQ
 gitlab.com/elixxir/crypto v0.0.7-0.20220513133141-46faee2d8fca/go.mod h1:cJF80ad9YCR+UcOlZNzfDVBAQqGEEhhs3y5taMEvXaE=
 gitlab.com/elixxir/crypto v0.0.7-0.20220516144816-71049ce09e4b h1:HZlcbi+rTr1MACtLoNUJDV2iTvy7JtkRjWWaPF45bcM=
 gitlab.com/elixxir/crypto v0.0.7-0.20220516144816-71049ce09e4b/go.mod h1:L3duHa+GppnsY8x22/ixrEdQSM7WXa1ORWPS90HZ/JI=
+gitlab.com/elixxir/crypto v0.0.7-0.20220606195831-6a6ac5f01c05 h1:q3KPJN/LfL2+5R24ls0ZhJmSn9FH4pC9BLBLlgKEBrE=
+gitlab.com/elixxir/crypto v0.0.7-0.20220606195831-6a6ac5f01c05/go.mod h1:TeqwH6LVx1uabvFB9IpYOdy9/myQbVwmW8Ktn0IQc/E=
+gitlab.com/elixxir/crypto v0.0.7-0.20220606201132-c370d5039cea h1:+FjwbKl6X9TDT7qd7gG5N5PSbziPWP3NgjK5ci1b7/8=
+gitlab.com/elixxir/crypto v0.0.7-0.20220606201132-c370d5039cea/go.mod h1:Oy+VWQ2Sa0Ybata3oTV+Yc46hkaDwAsuIMW0wJ01z2M=
 gitlab.com/elixxir/ekv v0.1.6 h1:M2hUSNhH/ChxDd+s8xBqSEKgoPtmE6hOEBqQ73KbN6A=
 gitlab.com/elixxir/ekv v0.1.6/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4=
 gitlab.com/elixxir/ekv v0.1.7 h1:OW2z+N4QCqqMFzouAwFTWWMKz0Y/PDhyYReN7gQ5NiQ=
@@ -458,6 +464,8 @@ gitlab.com/elixxir/primitives v0.0.3-0.20220325212708-5e2a7a385db7 h1:2yIEkxkPJb
 gitlab.com/elixxir/primitives v0.0.3-0.20220325212708-5e2a7a385db7/go.mod h1:MtFIyJUQn9P7djzVlBpEYkPNnnWFTjZvw89swoXY+QM=
 gitlab.com/elixxir/primitives v0.0.3-0.20220330212736-cce83b5f948f h1:bOX9nsG+ihvZAUP2OimpM/0UNIcfz5tYlvQfS2IFUoU=
 gitlab.com/elixxir/primitives v0.0.3-0.20220330212736-cce83b5f948f/go.mod h1:9Bb2+u+CDSwsEU5Droo6saDAXuBDvLRjexpBhPAYxhA=
+gitlab.com/elixxir/primitives v0.0.3-0.20220606195757-40f7a589347f h1:CTf2+ewHWYrzp5Ar3RwNvHePfTHyFniJTVjFW4zqoaE=
+gitlab.com/elixxir/primitives v0.0.3-0.20220606195757-40f7a589347f/go.mod h1:9Bb2+u+CDSwsEU5Droo6saDAXuBDvLRjexpBhPAYxhA=
 gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw=
 gitlab.com/xx_network/comms v0.0.4-0.20220223205228-7c4974139569/go.mod h1:isHnwem0v4rTcwwHP455FhVlFyPcHkHiVz+N3s/uCSI=
 gitlab.com/xx_network/comms v0.0.4-0.20220311192415-d95fe8906580 h1:IV0gDwdTxtCpc9Vkx7IeSStSqvG+0ZpF57X+OhTQDIM=
@@ -474,6 +482,10 @@ gitlab.com/xx_network/crypto v0.0.5-0.20220502201458-dabab1ef2982 h1:iUMwO/lIeOE
 gitlab.com/xx_network/crypto v0.0.5-0.20220502201458-dabab1ef2982/go.mod h1:/SJf+R75E+QepdTLh0H1/udsovxx2Q5ru34q1v0umKk=
 gitlab.com/xx_network/crypto v0.0.5-0.20220516143655-14f9153096ce h1:zkPtJLJUpoWDYD4z30nmKU8OvnIOnBvSu7e6q6WhY5A=
 gitlab.com/xx_network/crypto v0.0.5-0.20220516143655-14f9153096ce/go.mod h1:/SJf+R75E+QepdTLh0H1/udsovxx2Q5ru34q1v0umKk=
+gitlab.com/xx_network/crypto v0.0.5-0.20220606200131-b631a14ef56c h1:F3smqkDtpBdjCzn+quaQvPo1GLkam5JJYp3ppoWVa6M=
+gitlab.com/xx_network/crypto v0.0.5-0.20220606200131-b631a14ef56c/go.mod h1:/SJf+R75E+QepdTLh0H1/udsovxx2Q5ru34q1v0umKk=
+gitlab.com/xx_network/crypto v0.0.5-0.20220606200528-3f886fe49e81 h1:9HK48ZEGFKLm3HBcE/FdQitllJRYPPS0zeaiRL+MBhI=
+gitlab.com/xx_network/crypto v0.0.5-0.20220606200528-3f886fe49e81/go.mod h1:/SJf+R75E+QepdTLh0H1/udsovxx2Q5ru34q1v0umKk=
 gitlab.com/xx_network/primitives v0.0.0-20200803231956-9b192c57ea7c/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA=
 gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug=
 gitlab.com/xx_network/primitives v0.0.2/go.mod h1:cs0QlFpdMDI6lAo61lDRH2JZz+3aVkHy+QogOB6F/qc=
diff --git a/groupChat/receive.go b/groupChat/receive.go
index 56f8d56fd76cb2461b0612ee3492812596463e89..63e6f91c0c904351d2c8590d29ebb7aa9a6d98d8 100644
--- a/groupChat/receive.go
+++ b/groupChat/receive.go
@@ -9,6 +9,7 @@ package groupChat
 
 import (
 	"fmt"
+	"gitlab.com/xx_network/primitives/netTime"
 	"time"
 
 	"github.com/pkg/errors"
@@ -55,8 +56,10 @@ func (p *receptionProcessor) Process(message format.Message,
 	}
 
 	// Obtain the decryption key for the public message
+	// We use PRECOMPUTING here because all Rounds have that timestamp available to them
+	// QUEUED can be missing sometimes and cause a lot of hidden problems further down the line
 	key, err := getCryptKey(p.g.Key, pubMsg.GetSalt(), message.GetMac(),
-		pubMsg.GetPayload(), p.g.DhKeys, round.Timestamps[states.QUEUED])
+		pubMsg.GetPayload(), p.g.DhKeys, round.Timestamps[states.PRECOMPUTING])
 	if err != nil {
 		jww.ERROR.Printf(getDecryptionKeyErr, err)
 		return
@@ -125,6 +128,12 @@ func decryptMessage(g gs.Group, fingerprint format.Fingerprint,
 func getCryptKey(key group.Key, salt [group.SaltLen]byte, mac, payload []byte,
 	dhKeys gs.DhKeyList, roundTimestamp time.Time) (group.CryptKey, error) {
 
+	// If given zero time, try to guesstimate roundTimestamp as right now
+	if roundTimestamp.Equal(time.Unix(0, 0)) {
+		jww.ERROR.Printf("getCryptKey missing roundTimestamp")
+		roundTimestamp = netTime.Now()
+	}
+
 	// Compute the current epoch
 	epoch := group.ComputeEpoch(roundTimestamp)
 	for _, dhKey := range dhKeys {
diff --git a/groupChat/send_test.go b/groupChat/send_test.go
index bad4858985f742c681d090d92d5137b4e5bfd66f..71e252e5835ba1834f6108dbba0e6e813884df0b 100644
--- a/groupChat/send_test.go
+++ b/groupChat/send_test.go
@@ -51,7 +51,7 @@ func Test_manager_Send(t *testing.T) {
 	}
 
 	timestamps := make(map[states.Round]time.Time)
-	timestamps[states.QUEUED] = netTime.Now().Round(0)
+	timestamps[states.PRECOMPUTING] = netTime.Now().Round(0)
 	for _, msg := range messages {
 		reception.Process(msg, receptionID.EphemeralIdentity{
 			EphId: ephemeral.Id{1, 2, 3}, Source: &id.ID{4, 5, 6},