diff --git a/api/client.go b/api/client.go
index cd4e6f17e07780197da3f87d2cde2b075f0b193d..9e99657308a03695faf6077276f7bd816c7a797f 100644
--- a/api/client.go
+++ b/api/client.go
@@ -25,6 +25,7 @@ import (
 	"gitlab.com/elixxir/client/rekey"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/client/userRegistry"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/large"
 	"gitlab.com/elixxir/crypto/signature/rsa"
@@ -138,7 +139,7 @@ func newClient(s globals.Storage, locA, locB string, ndfJSON *ndf.NetworkDefinit
 	cmixGrp := cyclic.NewGroup(
 		large.NewIntFromString(cl.ndf.CMIX.Prime, 16),
 		large.NewIntFromString(cl.ndf.CMIX.Generator, 16))
-	user.InitUserRegistry(cmixGrp)
+	userRegistry.InitUserRegistry(cmixGrp)
 
 	cl.opStatus = func(int) {
 		return
@@ -194,22 +195,28 @@ func (cl *Client) Login(password string) (*id.ID, error) {
 		return nil, errors.Wrap(err,
 			"Login: Could not login: Could not get regState")
 	}
+	userData, err := cl.sessionV2.GetUserData()
+	if err != nil {
+		return nil, errors.Wrap(err,
+			"Login: Could not login: Could not get userData")
+	}
 
 	if regState <= user.KeyGenComplete {
 		return nil, errors.New("Cannot log a user in which has not " +
 			"completed registration ")
 	}
 
-	newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User,
-		rsa.CreatePrivateKeyPem(cl.session.GetRSAPrivateKey()),
-		rsa.CreatePublicKeyPem(cl.session.GetRSAPublicKey()),
-		cl.session.GetSalt())
+	newRm, err := io.NewReceptionManager(cl.rekeyChan,
+		userData.ThisUser.User,
+		rsa.CreatePrivateKeyPem(userData.RSAPrivateKey),
+		rsa.CreatePublicKeyPem(userData.RSAPublicKey),
+		userData.Salt)
 	if err != nil {
 		return nil, errors.Wrap(err, "Failed to create new reception manager")
 	}
 	newRm.Comms.Manager = cl.receptionManager.Comms.Manager
 	cl.receptionManager = newRm
-	return cl.session.GetCurrentUser().User, nil
+	return userData.ThisUser.User, nil
 }
 
 // Logout closes the connection to the server and the messageReceiver and clears out the client values,
@@ -360,9 +367,11 @@ func (cl *Client) InitListeners() error {
 	}
 
 	// Initialize UDB and nickname "bot" stuff here
-	bots.InitBots(cl.session, cl.receptionManager, cl.topology, transmissionHost)
+	bots.InitBots(cl.session, *cl.sessionV2, cl.receptionManager,
+		cl.topology, transmissionHost)
 	// Initialize Rekey listeners
-	rekey.InitRekey(cl.session, cl.receptionManager, cl.topology, transmissionHost, cl.rekeyChan)
+	rekey.InitRekey(cl.session, *cl.sessionV2, cl.receptionManager,
+		cl.topology, transmissionHost, cl.rekeyChan)
 	return nil
 }
 
@@ -447,8 +456,26 @@ func (cl *Client) GetSwitchboard() *switchboard.Switchboard {
 	return cl.session.GetSwitchboard()
 }
 
+func (cl *Client) GetUsername() string {
+	userData, _ := cl.sessionV2.GetUserData()
+	return userData.ThisUser.Username
+}
+
 func (cl *Client) GetCurrentUser() *id.ID {
-	return cl.session.GetCurrentUser().User
+	userData, _ := cl.sessionV2.GetUserData()
+	return userData.ThisUser.User
+}
+
+// FIXME: This is not exactly thread safe but is unlikely
+// to cause issues as username is not changed after
+// registration. Needs serious design considerations.
+func (cl *Client) ChangeUsername(username string) error {
+	userData, err := cl.sessionV2.GetUserData()
+	if err != nil {
+		return err
+	}
+	userData.ThisUser.Username = username
+	return cl.sessionV2.CommitUserData(userData)
 }
 
 func (cl *Client) GetKeyParams() *keyStore.KeyParams {
diff --git a/api/client_test.go b/api/client_test.go
index d20eb0eab0383a0c3cba6fb06ed61a712a176fc2..5c5d56311e698a524eb767e1c8863096c83e088d 100644
--- a/api/client_test.go
+++ b/api/client_test.go
@@ -170,13 +170,26 @@ func TestRegisterUserE2E(t *testing.T) {
 	privateKeyRSA, _ := rsa.GenerateKey(rng, TestKeySize)
 	publicKeyRSA := rsa.PublicKey{PublicKey: privateKeyRSA.PublicKey}
 
-	myUser := &user.User{User: userID, Username: "test"}
-	session := user.NewSession(testClient.storage,
-		myUser, &publicKeyRSA,
-		privateKeyRSA, nil, nil, myPubKeyCyclic, myPrivKeyCyclic, make([]byte, 1), cmixGrp,
-		e2eGrp, "password")
+	myUser := &storage.User{User: userID, Username: "test"}
+	session := user.NewSession(testClient.storage, "password")
+
+	userData := &storage.UserData{
+		ThisUser:         myUser,
+		RSAPrivateKey:    privateKeyRSA,
+		RSAPublicKey:     &publicKeyRSA,
+		CMIXDHPrivateKey: nil,
+		CMIXDHPublicKey:  nil,
+		E2EDHPrivateKey:  myPrivKeyCyclic,
+		E2EDHPublicKey:   myPubKeyCyclic,
+		CmixGrp:          cmixGrp,
+		E2EGrp:           e2eGrp,
+		Salt:             make([]byte, 1),
+	}
+	sessionV2 := storage.InitTestingSession(t)
+	sessionV2.CommitUserData(userData)
 
 	testClient.session = session
+	testClient.sessionV2 = sessionV2
 
 	err = testClient.registerUserE2E(&storage.Contact{
 		Id:        partner,
@@ -267,13 +280,26 @@ func TestRegisterUserE2E_CheckAllKeys(t *testing.T) {
 	privateKeyRSA, _ := rsa.GenerateKey(rng, TestKeySize)
 	publicKeyRSA := rsa.PublicKey{PublicKey: privateKeyRSA.PublicKey}
 
-	myUser := &user.User{User: userID, Username: "test"}
-	session := user.NewSession(testClient.storage,
-		myUser, &publicKeyRSA, privateKeyRSA, nil,
-		nil, myPubKeyCyclic, myPrivKeyCyclic,
-		make([]byte, 1), cmixGrp, e2eGrp, "password")
+	myUser := &storage.User{User: userID, Username: "test"}
+	session := user.NewSession(testClient.storage, "password")
+
+	userData := &storage.UserData{
+		ThisUser:         myUser,
+		RSAPrivateKey:    privateKeyRSA,
+		RSAPublicKey:     &publicKeyRSA,
+		CMIXDHPrivateKey: nil,
+		CMIXDHPublicKey:  nil,
+		E2EDHPrivateKey:  myPrivKeyCyclic,
+		E2EDHPublicKey:   myPubKeyCyclic,
+		CmixGrp:          cmixGrp,
+		E2EGrp:           e2eGrp,
+		Salt:             make([]byte, 1),
+	}
+	sessionV2 := storage.InitTestingSession(t)
+	sessionV2.CommitUserData(userData)
 
 	testClient.session = session
+	testClient.sessionV2 = sessionV2
 
 	err = testClient.registerUserE2E(&storage.Contact{
 		Id:        partner,
diff --git a/api/mockserver_test.go b/api/mockserver_test.go
index 804401810beab064de8657dcd2588ef4e364a871..870c01c7c4d55a5a2dbac571b5b00a842df5f854 100644
--- a/api/mockserver_test.go
+++ b/api/mockserver_test.go
@@ -11,9 +11,9 @@ import (
 	"fmt"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/io"
-	//clientStorage "gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/client/userRegistry"
 	"gitlab.com/elixxir/comms/gateway"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/comms/notificationBot"
@@ -234,9 +234,23 @@ func TestRegister_InvalidRegState(t *testing.T) {
 	}
 	cmixPrivKey, cmixPubKey, err := generateCmixKeys(cmixGrp)
 
-	client.session = user.NewSession(nil, usr, pubKey, privKey, cmixPubKey, cmixPrivKey, e2ePubKey, e2ePrivKey, salt, cmixGrp, e2eGrp, "")
+	client.session = user.NewSession(nil, "password")
 	client.sessionV2, _ = storage.Init(".ekv-invalidregstate", "password")
 
+	userData := &storage.UserData{
+		ThisUser:         usr,
+		RSAPrivateKey:    privKey,
+		RSAPublicKey:     pubKey,
+		CMIXDHPrivateKey: cmixPrivKey,
+		CMIXDHPublicKey:  cmixPubKey,
+		E2EDHPrivateKey:  e2ePrivKey,
+		E2EDHPublicKey:   e2ePubKey,
+		CmixGrp:          cmixGrp,
+		E2EGrp:           e2eGrp,
+		Salt:             salt,
+	}
+	client.sessionV2.CommitUserData(userData)
+
 	//
 	_, err = client.RegisterWithPermissioning(false, ValidRegCode)
 	if err == nil {
@@ -261,8 +275,8 @@ func TestRegister_DeletedUserReturnsErr(t *testing.T) {
 	}
 
 	// ...
-	tempUser, _ := user.Users.GetUser(id.NewIdFromUInt(5, id.User, t))
-	user.Users.DeleteUser(id.NewIdFromUInt(5, id.User, t))
+	tempUser, _ := userRegistry.Users.GetUser(id.NewIdFromUInt(5, id.User, t))
+	userRegistry.Users.DeleteUser(id.NewIdFromUInt(5, id.User, t))
 	err = client.GenerateKeys(nil, "password")
 	if err != nil {
 		t.Errorf("Could not generate Keys: %+v", err)
@@ -275,7 +289,7 @@ func TestRegister_DeletedUserReturnsErr(t *testing.T) {
 	}
 
 	// ...
-	user.Users.UpsertUser(tempUser)
+	userRegistry.Users.UpsertUser(tempUser)
 	//Disconnect and shutdown servers
 	disconnectServers()
 }
diff --git a/api/private.go b/api/private.go
index c01b5a2827e6a9b9ba696dcfc402e0e46acb0822..06b3addf5bdef9f96f038dd2704e8281d7e4ee1b 100644
--- a/api/private.go
+++ b/api/private.go
@@ -15,6 +15,7 @@ import (
 	"gitlab.com/elixxir/client/keyStore"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/client/userRegistry"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/csprng"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -32,15 +33,15 @@ const PermissioningAddrID = "Permissioning"
 
 // precannedRegister is a helper function for Register
 // It handles the precanned registration case
-func (cl *Client) precannedRegister(registrationCode string) (*user.User, *id.ID, map[id.ID]user.NodeKeys, error) {
+func (cl *Client) precannedRegister(registrationCode string) (*storage.User, *id.ID, map[id.ID]user.NodeKeys, error) {
 	var successLook bool
 	var UID *id.ID
-	var u *user.User
+	var u *storage.User
 	var err error
 
 	nk := make(map[id.ID]user.NodeKeys)
 
-	UID, successLook = user.Users.LookupUser(registrationCode)
+	UID, successLook = userRegistry.Users.LookupUser(registrationCode)
 
 	globals.Log.DEBUG.Printf("UID: %+v, success: %+v", UID, successLook)
 
@@ -49,14 +50,14 @@ func (cl *Client) precannedRegister(registrationCode string) (*user.User, *id.ID
 	}
 
 	var successGet bool
-	u, successGet = user.Users.GetUser(UID)
+	u, successGet = userRegistry.Users.GetUser(UID)
 
 	if !successGet {
 		err = errors.New("precannedRegister: could not register due to ID lookup failure")
 		return nil, nil, nil, err
 	}
 
-	nodekeys, successKeys := user.Users.LookupKeys(u.User)
+	nodekeys, successKeys := userRegistry.Users.LookupKeys(u.User)
 
 	if !successKeys {
 		err = errors.New("precannedRegister: could not register due to missing user keys")
@@ -217,17 +218,22 @@ func (cl *Client) registerUserE2E(partner *storage.Contact) error {
 			"been searched for before", partner.Id))
 	}
 
-	if cl.session.GetCurrentUser().User.Cmp(partner.Id) {
+	userData, err := cl.sessionV2.GetUserData()
+	if err != nil {
+		return err
+	}
+
+	if userData.ThisUser.User.Cmp(partner.Id) {
 		return errors.New("cannot search for yourself on UDB")
 	}
 
 	// Get needed variables from session
-	grp := cl.session.GetE2EGroup()
-	userID := cl.session.GetCurrentUser().User
+	grp := userData.E2EGrp
+	userID := userData.ThisUser.User
 
 	// Create user private key and partner public key
 	// in the group
-	privKeyCyclic := cl.session.GetE2EDHPrivateKey()
+	privKeyCyclic := userData.E2EDHPrivateKey
 	publicKeyCyclic := grp.NewIntFromBytes(partner.PublicKey)
 
 	// Generate baseKey
@@ -301,13 +307,38 @@ func (cl *Client) GenerateKeys(rsaPrivKey *rsa.PrivateKey,
 		return err
 	}
 
-	cl.session = user.NewSession(cl.storage, usr, pubKey, privKey, cmixPubKey,
-		cmixPrivKey, e2ePubKey, e2ePrivKey, salt, cmixGrp, e2eGrp, password)
+	cl.session = user.NewSession(cl.storage, password)
+	locA, _ := cl.storage.GetLocation()
+	err = cl.setStorage(locA, password)
+	if err != nil {
+		return err
+	}
 
-	newRm, err := io.NewReceptionManager(cl.rekeyChan, cl.session.GetCurrentUser().User,
-		rsa.CreatePrivateKeyPem(privKey), rsa.CreatePublicKeyPem(pubKey), salt)
+	userData := &storage.UserData{
+		ThisUser: &storage.User{
+			User:     usr.User,
+			Username: usr.Username,
+			Precan:   usr.Precan,
+		},
+		RSAPrivateKey:    privKey,
+		RSAPublicKey:     pubKey,
+		CMIXDHPrivateKey: cmixPrivKey,
+		CMIXDHPublicKey:  cmixPubKey,
+		E2EDHPrivateKey:  e2ePrivKey,
+		E2EDHPublicKey:   e2ePubKey,
+		CmixGrp:          cmixGrp,
+		E2EGrp:           e2eGrp,
+		Salt:             salt,
+	}
+	cl.sessionV2.CommitUserData(userData)
+
+	newRm, err := io.NewReceptionManager(cl.rekeyChan,
+		usr.User,
+		rsa.CreatePrivateKeyPem(privKey),
+		rsa.CreatePublicKeyPem(pubKey),
+		salt)
 	if err != nil {
-		return errors.Wrap(err, "Failed to create new reception manager")
+		return errors.Wrap(err, "Couldn't create reception manager")
 	}
 	if cl.receptionManager != nil {
 		// Use the old comms manager if it exists
@@ -315,12 +346,6 @@ func (cl *Client) GenerateKeys(rsaPrivKey *rsa.PrivateKey,
 	}
 	cl.receptionManager = newRm
 
-	locA, _ := cl.storage.GetLocation()
-	err = cl.setStorage(locA, password)
-	if err != nil {
-		return err
-	}
-
 	//store the session
 	return cl.session.StoreSession()
 }
@@ -400,7 +425,8 @@ func generateE2eKeys(cmixGrp, e2eGrp *cyclic.Group) (e2ePrivateKey, e2ePublicKey
 
 //generateUserInformation serves as a helper function for RegisterUser.
 // It generates a salt s.t. it can create a user and their ID
-func generateUserInformation(publicKeyRSA *rsa.PublicKey) ([]byte, *id.ID, *user.User, error) {
+func generateUserInformation(publicKeyRSA *rsa.PublicKey) ([]byte, *id.ID,
+	*storage.User, error) {
 	//Generate salt for UserID
 	salt := make([]byte, SaltSize)
 	_, err := csprng.NewSystemRNG().Read(salt)
@@ -415,8 +441,8 @@ func generateUserInformation(publicKeyRSA *rsa.PublicKey) ([]byte, *id.ID, *user
 		return nil, nil, nil, err
 	}
 
-	usr := user.Users.NewUser(userId, "")
-	user.Users.UpsertUser(usr)
+	usr := userRegistry.Users.NewUser(userId, "")
+	userRegistry.Users.UpsertUser(usr)
 
 	return salt, userId, usr, nil
 }
diff --git a/api/private_test.go b/api/private_test.go
index 514a19a500da8b0c04cfc5d16b6e0a5065590709..19d8693ffad3adef8f8c05f31d57e0457d8cce4a 100644
--- a/api/private_test.go
+++ b/api/private_test.go
@@ -7,7 +7,7 @@ package api
 
 import (
 	"bytes"
-	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/client/userRegistry"
 	"gitlab.com/elixxir/crypto/csprng"
 	"gitlab.com/elixxir/crypto/signature/rsa"
 	"reflect"
@@ -111,13 +111,13 @@ func TestGenerateE2eKeys(t *testing.T) {
 //Happy path: tests that it generates a user and puts in the registry
 func TestGenerateUserInformation_EmptyNick(t *testing.T) {
 	grp, _ := generateGroups(def)
-	user.InitUserRegistry(grp)
+	userRegistry.InitUserRegistry(grp)
 	_, pubkey, _ := generateRsaKeys(nil)
 	_, uid, usr, err := generateUserInformation(pubkey)
 	if err != nil {
 		t.Errorf("%+v", err)
 	}
-	retrievedUser, ok := user.Users.GetUser(uid)
+	retrievedUser, ok := userRegistry.Users.GetUser(uid)
 	if !ok {
 		t.Errorf("UserId not inserted into registry")
 	}
@@ -135,7 +135,7 @@ func TestGenerateUserInformation_EmptyNick(t *testing.T) {
 //Happy path: test GenerateUser with a nickname and puts in registry
 func TestGenerateUserInformation(t *testing.T) {
 	grp, _ := generateGroups(def)
-	user.InitUserRegistry(grp)
+	userRegistry.InitUserRegistry(grp)
 	nickName := "test"
 	_, pubkey, _ := generateRsaKeys(nil)
 	_, uid, usr, err := generateUserInformation(pubkey)
@@ -144,7 +144,7 @@ func TestGenerateUserInformation(t *testing.T) {
 		t.Errorf("%+v", err)
 	}
 
-	retrievedUser, ok := user.Users.GetUser(uid)
+	retrievedUser, ok := userRegistry.Users.GetUser(uid)
 	if !ok {
 		t.Errorf("UserId not inserted into registry")
 	}
diff --git a/api/register.go b/api/register.go
index 9103b8b0c9c0f196dbfe86c2073f9c557162133a..4348a17ab8d9a6cbb044ddd6696e93c3347edddd 100644
--- a/api/register.go
+++ b/api/register.go
@@ -39,7 +39,11 @@ func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string
 	if regState != user.KeyGenComplete {
 		return nil, errors.Errorf("Attempting to register before key generation!")
 	}
-	usr := cl.session.GetCurrentUser()
+	userData, err := cl.sessionV2.GetUserData()
+	if err != nil {
+		return nil, err
+	}
+	usr := userData.ThisUser
 	UID := usr.User
 
 	//Initialized response from Registration Server
@@ -58,7 +62,9 @@ func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string
 		}
 
 		//overwrite the user object
-		cl.session.(*user.SessionObj).CurrentUser = usr
+		usr.Precan = true
+		userData.ThisUser = usr
+		cl.sessionV2.CommitUserData(userData)
 
 		//store the node keys
 		for n, k := range nodeKeyMap {
@@ -73,7 +79,9 @@ func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode string
 
 	} else {
 		// Or register with the permissioning server and generate user information
-		regValidationSignature, err = cl.registerWithPermissioning(registrationCode, cl.session.GetRSAPublicKey())
+		regValidationSignature, err = cl.registerWithPermissioning(
+			registrationCode,
+			userData.RSAPublicKey)
 		if err != nil {
 			globals.Log.INFO.Printf(err.Error())
 			return &id.ZeroUser, err
@@ -112,6 +120,10 @@ func (cl *Client) RegisterWithUDB(username string, timeout time.Duration) error
 	if err != nil {
 		return err
 	}
+	userData, err := cl.sessionV2.GetUserData()
+	if err != nil {
+		return err
+	}
 
 	if regState != user.PermissioningComplete {
 		return errors.New("Cannot register with UDB when registration " +
@@ -119,16 +131,14 @@ func (cl *Client) RegisterWithUDB(username string, timeout time.Duration) error
 	}
 
 	if username != "" {
-		err := cl.session.ChangeUsername(username)
-		if err != nil {
-			return err
-		}
+		userData.ThisUser.Username = username
+		cl.sessionV2.CommitUserData(userData)
 
 		globals.Log.INFO.Printf("Registering user as %s with UDB", username)
 
 		valueType := "EMAIL"
 
-		publicKeyBytes := cl.session.GetE2EDHPublicKey().Bytes()
+		publicKeyBytes := userData.E2EDHPublicKey.Bytes()
 		err = bots.Register(valueType, username, publicKeyBytes, cl.opStatus, timeout)
 		if err != nil {
 			return errors.Errorf("Could not register with UDB: %s", err)
@@ -164,24 +174,31 @@ func (cl *Client) RegisterWithUDB(username string, timeout time.Duration) error
 
 //RegisterWithNodes registers the client with all the nodes within the ndf
 func (cl *Client) RegisterWithNodes() error {
+
+	userData, err := cl.sessionV2.GetUserData()
+	if err != nil {
+		return err
+	}
+
 	cl.opStatus(globals.REG_NODE)
 	session := cl.GetSession()
 	//Load Cmix keys & group
-	cmixDHPrivKey := session.GetCMIXDHPrivateKey()
-	cmixDHPubKey := session.GetCMIXDHPublicKey()
-	cmixGrp := session.GetCmixGroup()
+	cmixDHPrivKey := userData.CMIXDHPrivateKey
+	cmixDHPubKey := userData.CMIXDHPublicKey
+	cmixGrp := userData.CmixGrp
 
 	//Load the rsa keys
-	rsaPubKey := session.GetRSAPublicKey()
-	rsaPrivKey := session.GetRSAPrivateKey()
+	rsaPubKey := userData.RSAPublicKey
+	rsaPrivKey := userData.RSAPrivateKey
 
 	//Load the user ID
-	UID := session.GetCurrentUser().User
-	usr := session.GetCurrentUser()
+	UID := userData.ThisUser.User
+	usr := userData.ThisUser
 	//Load the registration signature
 	regSignature, err := cl.sessionV2.GetRegValidationSig()
 	if err != nil && !os.IsNotExist(err) {
-		return errors.Errorf("Failed to get registration signature: %v", err)
+		return errors.Errorf("Failed to get registration signature: %v",
+			err)
 	}
 
 	// Storage of the registration signature was broken in previous releases.
@@ -199,7 +216,7 @@ func (cl *Client) RegisterWithNodes() error {
 	// get the signature again from permissioning if it is absent
 	if !usr.Precan && !rsa.IsValidSignature(regPubKey, regSignature) {
 		// Or register with the permissioning server and generate user information
-		regSignature, err := cl.registerWithPermissioning("", cl.session.GetRSAPublicKey())
+		regSignature, err := cl.registerWithPermissioning("", userData.RSAPublicKey)
 		if err != nil {
 			globals.Log.INFO.Printf(err.Error())
 			return err
@@ -228,7 +245,7 @@ func (cl *Client) RegisterWithNodes() error {
 		return err
 	}
 
-	salt := session.GetSalt()
+	salt := userData.Salt
 
 	// This variable keeps track of whether there were new registrations
 	// required, thus requiring the state file to be saved again
diff --git a/api/register_test.go b/api/register_test.go
index 5e0c5edddd1f2671bf2e98f0106213724cb5b3e7..34cabf70b5554532b12ca961561246775e1ad6eb 100644
--- a/api/register_test.go
+++ b/api/register_test.go
@@ -7,6 +7,7 @@ package api
 
 import (
 	"gitlab.com/elixxir/client/io"
+	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/xx_network/primitives/id"
 	"testing"
@@ -38,19 +39,9 @@ func TestRegistrationGob(t *testing.T) {
 		t.Error(err)
 	}
 
-	err = testClient.session.StoreSession()
-	if err != nil {
-		t.Error(err)
-	}
-
-	// get the gob out of there again
-	Session, err := user.LoadSession(testClient.storage,
-		"1234")
-	if err != nil {
-		t.Error(err)
-	}
+	userData, _ := testClient.sessionV2.GetUserData()
 
-	VerifyRegisterGobUser(Session, t)
+	VerifyRegisterGobUser(userData.ThisUser, t)
 
 	disconnectServers()
 }
@@ -88,26 +79,21 @@ func TestClient_Register(t *testing.T) {
 		t.Error(err)
 	}
 
-	// get the gob out of there again
-	Session, err := user.LoadSession(testClient.storage,
-		"password")
-	if err != nil {
-		t.Error(err)
-	}
+	userData, _ := testClient.sessionV2.GetUserData()
 
-	VerifyRegisterGobUser(Session, t)
+	VerifyRegisterGobUser(userData.ThisUser, t)
 
 	disconnectServers()
 }
 
 //Verify the user from the session make in the registration above matches expected user
-func VerifyRegisterGobUser(session user.Session, t *testing.T) {
+func VerifyRegisterGobUser(curUser *storage.User, t *testing.T) {
 
 	expectedUser := id.NewIdFromUInt(5, id.User, t)
 
-	if !session.GetCurrentUser().User.Cmp(expectedUser) {
+	if !curUser.User.Cmp(expectedUser) {
 		t.Errorf("Incorrect User ID; \n   expected: %q \n   recieved: %q",
-			expectedUser, session.GetCurrentUser().User)
+			expectedUser, curUser.User)
 	}
 }
 
diff --git a/bindings/client.go b/bindings/client.go
index 9625981e614043d2c7fc8b6487c3b3f6c514cfe4..ae5494dc6dd5878716f4369b3e4bfa914d1aea43 100644
--- a/bindings/client.go
+++ b/bindings/client.go
@@ -178,13 +178,13 @@ func (cl *Client) Login(UID []byte, password string) ([]byte, error) {
 func (cl *Client) GetUsername() string {
 	globals.Log.INFO.Printf("Binding call: GetUsername()")
 
-	return cl.client.GetSession().GetCurrentUser().Username
+	return cl.client.GetUsername()
 }
 
 func (cl *Client) GetUserID() []byte {
 	globals.Log.INFO.Printf("Binding call: GetUserID()")
 
-	return cl.client.GetSession().GetCurrentUser().User[:]
+	return cl.client.GetCurrentUser().Bytes()
 }
 
 type MessageReceiverCallback interface {
@@ -264,7 +264,7 @@ func (cl *Client) ChangeUsername(un string) error {
 		return errors.New("Can only change username during " +
 			"PermissioningComplete registration state")
 	}
-	return cl.client.GetSession().ChangeUsername(un)
+	return cl.client.ChangeUsername(un)
 }
 
 // gets the curent registration status.  they cane be:
diff --git a/bots/bots.go b/bots/bots.go
index 815e183370da872d587fb893445d0824326b43a9..baee89c86d454579bebcd440b6acaba181a65f9a 100644
--- a/bots/bots.go
+++ b/bots/bots.go
@@ -5,6 +5,7 @@ import (
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/io"
 	"gitlab.com/elixxir/client/parse"
+	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/primitives/switchboard"
 	"gitlab.com/xx_network/comms/connect"
@@ -12,6 +13,7 @@ import (
 )
 
 var session user.Session
+var sessionV2 storage.Session
 var topology *connect.Circuit
 var comms io.Communications
 var transmissionHost *connect.Host
@@ -30,12 +32,14 @@ var searchResponseListener channelResponseListener
 var nicknameResponseListener channelResponseListener
 
 // Nickname request listener
-type nickReqListener struct{}
+type nickReqListener struct {
+	MyNick string
+}
 
 // Nickname listener simply replies with message containing user's nick
 func (l *nickReqListener) Hear(msg switchboard.Item, isHeardElsewhere bool, i ...interface{}) {
 	m := msg.(*parse.Message)
-	nick := session.GetCurrentUser().Username
+	nick := l.MyNick
 	resp := parse.Pack(&parse.TypedBody{
 		MessageType: int32(cmixproto.Type_NICKNAME_RESPONSE),
 		Body:        []byte(nick),
@@ -47,7 +51,15 @@ func (l *nickReqListener) Hear(msg switchboard.Item, isHeardElsewhere bool, i ..
 var nicknameRequestListener nickReqListener
 
 // InitBots is called internally by the Login API
-func InitBots(s user.Session, m io.Communications, top *connect.Circuit, host *connect.Host) {
+func InitBots(s user.Session, s2 storage.Session, m io.Communications, top *connect.Circuit, host *connect.Host) {
+
+	userData, err := s2.GetUserData()
+	if err != nil {
+		globals.Log.FATAL.Panicf("Could not load userdata: %+v", err)
+	}
+
+	userNick := userData.ThisUser.Username
+
 	// FIXME: these all need to be used in non-blocking threads if we are
 	// going to do it this way...
 	msgBufSize := 100
@@ -55,10 +67,13 @@ func InitBots(s user.Session, m io.Communications, top *connect.Circuit, host *c
 	getKeyResponseListener = make(channelResponseListener, msgBufSize)
 	registerResponseListener = make(channelResponseListener, msgBufSize)
 	searchResponseListener = make(channelResponseListener, msgBufSize)
-	nicknameRequestListener = nickReqListener{}
+	nicknameRequestListener = nickReqListener{
+		MyNick: userNick,
+	}
 	nicknameResponseListener = make(channelResponseListener, msgBufSize)
 
 	session = s
+	sessionV2 = s2
 	topology = top
 	comms = m
 	transmissionHost = host
diff --git a/bots/bots_test.go b/bots/bots_test.go
index 1efab52c84adcedf5b2a4b28b9e839734f736e39..042b65b71d29bb4b50c1806f6c951d879bbe23c3 100644
--- a/bots/bots_test.go
+++ b/bots/bots_test.go
@@ -16,6 +16,7 @@ import (
 	"gitlab.com/elixxir/client/cmixproto"
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/parse"
+	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/large"
@@ -64,7 +65,7 @@ var keyFingerprint string
 var pubKey []byte
 
 func TestMain(m *testing.M) {
-	u := &user.User{
+	u := &storage.User{
 		User:     new(id.ID),
 		Username: "Bernie",
 	}
@@ -73,10 +74,16 @@ func TestMain(m *testing.M) {
 
 	cmixGrp, e2eGrp := getGroups()
 
-	fakeSession := user.NewSession(&globals.RamStorage{},
-		u, nil, nil, nil,
-		nil, nil, nil, nil,
-		cmixGrp, e2eGrp, "password")
+	fakeSession := user.NewSession(&globals.RamStorage{}, "password")
+	fakeSession2 := storage.InitTestingSession(m)
+	fakeSession2.CommitUserData(&storage.UserData{
+		ThisUser: &storage.User{
+			User:     u.User,
+			Username: u.Username,
+		},
+		CmixGrp: cmixGrp,
+		E2EGrp:  e2eGrp,
+	})
 	fakeComm := &dummyMessaging{
 		listener: ListenCh,
 	}
@@ -85,7 +92,7 @@ func TestMain(m *testing.M) {
 	nodeID.SetType(id.Node)
 	topology := connect.NewCircuit([]*id.ID{nodeID})
 
-	InitBots(fakeSession, fakeComm, topology, &h)
+	InitBots(fakeSession, *fakeSession2, fakeComm, topology, &h)
 
 	// Make the reception channels buffered for this test
 	// which overwrites the channels registered in InitBots
@@ -158,14 +165,17 @@ func TestSearch(t *testing.T) {
 // Test LookupNick function
 func TestNicknameFunctions(t *testing.T) {
 	// Test receiving a nickname request
+	userData, _ := sessionV2.GetUserData()
+	curUser := userData.ThisUser.User
+
 	msg := &parse.Message{
-		Sender: session.GetCurrentUser().User,
+		Sender: curUser,
 		TypedBody: parse.TypedBody{
 			MessageType: int32(cmixproto.Type_NICKNAME_REQUEST),
 			Body:        []byte{},
 		},
 		InferredType: parse.Unencrypted,
-		Receiver:     session.GetCurrentUser().User,
+		Receiver:     curUser,
 	}
 	session.GetSwitchboard().Speak(msg)
 
@@ -173,23 +183,23 @@ func TestNicknameFunctions(t *testing.T) {
 
 	// send response to switchboard
 	msg = &parse.Message{
-		Sender: session.GetCurrentUser().User,
+		Sender: curUser,
 		TypedBody: parse.TypedBody{
 			MessageType: int32(cmixproto.Type_NICKNAME_RESPONSE),
-			Body:        []byte(session.GetCurrentUser().Username),
+			Body:        []byte(userData.ThisUser.Username),
 		},
 		InferredType: parse.Unencrypted,
-		Receiver:     session.GetCurrentUser().User,
+		Receiver:     curUser,
 	}
 	session.GetSwitchboard().Speak(msg)
 	// AFter sending the message, perform the lookup to read it
-	nick, err := LookupNick(session.GetCurrentUser().User)
+	nick, err := LookupNick(curUser)
 	if err != nil {
 		t.Errorf("Error on LookupNick: %s", err.Error())
 	}
-	if nick != session.GetCurrentUser().Username {
+	if nick != userData.ThisUser.Username {
 		t.Errorf("LookupNick returned wrong value. Expected %s,"+
-			" Got %s", session.GetCurrentUser().Username, nick)
+			" Got %s", userData.ThisUser.Username, nick)
 	}
 }
 
@@ -220,9 +230,10 @@ func (e *errorMessaging) MessageReceiver(session user.Session,
 
 // Test LookupNick returns error on sending problem
 func TestLookupNick_error(t *testing.T) {
+	userData, _ := sessionV2.GetUserData()
 	// Replace comms with errorMessaging
 	comms = &errorMessaging{}
-	_, err := LookupNick(session.GetCurrentUser().User)
+	_, err := LookupNick(userData.ThisUser.User)
 	if err == nil {
 		t.Errorf("LookupNick should have returned an error")
 	}
diff --git a/cmd/root.go b/cmd/root.go
index ed8473d5521f96dbd7ec8afe1f8aae18268645f3..bd9b32d6ed6f694e284cb5136ea69978fc651d84 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -21,6 +21,7 @@ import (
 	"gitlab.com/elixxir/client/io"
 	"gitlab.com/elixxir/client/parse"
 	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/client/userRegistry"
 	"gitlab.com/elixxir/crypto/signature/rsa"
 	"gitlab.com/elixxir/primitives/switchboard"
 	"gitlab.com/elixxir/primitives/utils"
@@ -198,7 +199,7 @@ func sessionInitialization() (*id.ID, string, *api.Client) {
 			uid := new(id.ID)
 			binary.BigEndian.PutUint64(uid[:], userId)
 			uid.SetType(id.User)
-			regCode = user.RegistrationCode(uid)
+			regCode = userRegistry.RegistrationCode(uid)
 		}
 
 		globals.Log.INFO.Printf("Building keys...")
@@ -269,7 +270,7 @@ func sessionInitialization() (*id.ID, string, *api.Client) {
 	if err != nil {
 		globals.Log.FATAL.Panicf("Could not login: %v", err)
 	}
-	return uid, client.GetSession().GetCurrentUser().Username, client
+	return uid, client.GetUsername(), client
 }
 
 func setKeyParams(client *api.Client) {
@@ -317,7 +318,7 @@ type FallbackListener struct {
 func (l *FallbackListener) Hear(item switchboard.Item, isHeardElsewhere bool, i ...interface{}) {
 	if !isHeardElsewhere {
 		message := item.(*parse.Message)
-		sender, ok := user.Users.GetUser(message.Sender)
+		sender, ok := userRegistry.Users.GetUser(message.Sender)
 		var senderNick string
 		if !ok {
 			globals.Log.ERROR.Printf("Couldn't get sender %v", message.Sender)
@@ -345,12 +346,12 @@ func (l *TextListener) Hear(item switchboard.Item, isHeardElsewhere bool, i ...i
 			err.Error())
 	}
 
-	sender, ok := user.Users.GetUser(message.Sender)
+	sender, ok := userRegistry.Users.GetUser(message.Sender)
 	var senderNick string
 	if !ok {
 		globals.Log.INFO.Printf("First message from sender %v", printIDNice(message.Sender))
-		u := user.Users.NewUser(message.Sender, base64.StdEncoding.EncodeToString(message.Sender[:]))
-		user.Users.UpsertUser(u)
+		u := userRegistry.Users.NewUser(message.Sender, base64.StdEncoding.EncodeToString(message.Sender[:]))
+		userRegistry.Users.UpsertUser(u)
 		senderNick = u.Username
 	} else {
 		senderNick = sender.Username
@@ -486,7 +487,7 @@ var rootCmd = &cobra.Command{
 		if message != "" {
 			// Get the recipient's nick
 			recipientNick := ""
-			u, ok := user.Users.GetUser(recipientId)
+			u, ok := userRegistry.Users.GetUser(recipientId)
 			if ok {
 				recipientNick = u.Username
 			}
diff --git a/crypto/encrypt.go b/crypto/encrypt.go
index 278d142d50ac681aac1a25b262fcbff401c88f78..bb3fb592f4f6dfc89b5dc9a0a8af16378b0d5b67 100644
--- a/crypto/encrypt.go
+++ b/crypto/encrypt.go
@@ -38,7 +38,13 @@ func CMIXEncrypt(session user.Session, topology *connect.Circuit, salt []byte,
 		baseKeys[i] = key.TransmissionKey
 	}
 
-	ecrMsg := cmix.ClientEncrypt(session.GetCmixGroup(), msg, salt, baseKeys)
+	userData, err := SessionV2.GetUserData()
+
+	if err != nil {
+		globals.Log.FATAL.Panicf("could not get userData: %+v", err)
+	}
+
+	ecrMsg := cmix.ClientEncrypt(userData.CmixGrp, msg, salt, baseKeys)
 
 	h, err := hash.NewCMixHash()
 	if err != nil {
diff --git a/crypto/encryptdecrypt_test.go b/crypto/encryptdecrypt_test.go
index a74a65d9bd79480f233875e8ed5238fa4025ae4e..247748d72a6167feb8fbaa08ce94ecd283bb577b 100644
--- a/crypto/encryptdecrypt_test.go
+++ b/crypto/encryptdecrypt_test.go
@@ -12,6 +12,7 @@ import (
 	"fmt"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/client/userRegistry"
 	pb "gitlab.com/elixxir/comms/mixmessages"
 	"gitlab.com/elixxir/crypto/cmix"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -41,12 +42,12 @@ func setup() {
 
 	cmixGrp, e2eGrp := getGroups()
 
-	user.InitUserRegistry(cmixGrp)
+	userRegistry.InitUserRegistry(cmixGrp)
 
 	UID := new(id.ID)
 	binary.BigEndian.PutUint64(UID[:], 18)
 	UID.SetType(id.User)
-	u, ok := user.Users.GetUser(UID)
+	u, ok := userRegistry.Users.GetUser(UID)
 	if !ok {
 		panic("Didn't get user 18 from registry")
 	}
@@ -69,12 +70,17 @@ func setup() {
 
 	h, _ := blake2b.New256(nil)
 
-	session = user.NewSession(nil, u, nil, nil,
-		nil, nil, nil,
-		nil, nil, cmixGrp, e2eGrp, "password")
+	session = user.NewSession(nil, "password")
 
 	SessionV2, _ = storage.Init(".ekvcryptotest", "password")
 
+	userData := &storage.UserData{
+		ThisUser: u,
+		CmixGrp:  cmixGrp,
+		E2EGrp:   e2eGrp,
+	}
+	SessionV2.CommitUserData(userData)
+
 	for i := 0; i < numNodes; i++ {
 
 		nk := user.NodeKeys{}
diff --git a/io/receive.go b/io/receive.go
index 43737aff93f3b365da658e2e0f58c3445f35240b..102ca0954ed00514c5cfe1ae442a2982644aa2d8 100644
--- a/io/receive.go
+++ b/io/receive.go
@@ -39,8 +39,14 @@ func (rm *ReceptionManager) MessageReceiver(session user.Session, delay time.Dur
 	if session == nil {
 		globals.Log.FATAL.Panicf("No user session available")
 	}
+
+	userData, err := SessionV2.GetUserData()
+	if err != nil {
+		globals.Log.FATAL.Panicf("No user data available: %+v", err)
+	}
+
 	pollingMessage := pb.ClientRequest{
-		UserID: session.GetCurrentUser().User.Bytes(),
+		UserID: userData.ThisUser.User.Bytes(),
 	}
 	quit := session.GetQuitChan()
 	NumChecks := 0
@@ -120,6 +126,13 @@ func (rm *ReceptionManager) MessageReceiver(session user.Session, delay time.Dur
 
 func handleE2EReceiving(session user.Session,
 	message *format.Message) (*id.ID, bool, error) {
+
+	userData, err := SessionV2.GetUserData()
+	if err != nil {
+		return nil, false, fmt.Errorf("Could not get user data: %+v",
+			err)
+	}
+
 	keyFingerprint := message.GetKeyFP()
 
 	// Lookup reception key
@@ -138,11 +151,12 @@ func handleE2EReceiving(session user.Session,
 	sender := recpKey.GetManager().GetPartner()
 
 	globals.Log.DEBUG.Printf("E2E decrypting message")
-	var err error
 	if rekey {
-		err = crypto.E2EDecryptUnsafe(session.GetE2EGroup(), recpKey.GetKey(), message)
+		err = crypto.E2EDecryptUnsafe(userData.E2EGrp, recpKey.GetKey(),
+			message)
 	} else {
-		err = crypto.E2EDecrypt(session.GetE2EGroup(), recpKey.GetKey(), message)
+		err = crypto.E2EDecrypt(userData.E2EGrp, recpKey.GetKey(),
+			message)
 	}
 
 	if err != nil {
@@ -163,7 +177,7 @@ func handleE2EReceiving(session user.Session,
 				Body:        partnerPubKey,
 			},
 			InferredType: parse.Rekey,
-			Receiver:     session.GetCurrentUser().User,
+			Receiver:     userData.ThisUser.User,
 		}
 		go session.GetSwitchboard().Speak(rekeyMsg)
 	}
@@ -180,6 +194,12 @@ func (rm *ReceptionManager) receiveMessagesFromGateway(session user.Session,
 		globals.Log.WARN.Printf("SessionV2 is nil")
 		return nil, errors.New("SessionV2 is nil")
 	}
+	userData, err := SessionV2.GetUserData()
+	if err != nil {
+		globals.Log.WARN.Printf("Could not get UserData: %+v", err)
+		return nil, err
+	}
+
 	pollingMessage.LastMessageID, err = SessionV2.GetLastMessageId()
 	if err != nil {
 		globals.Log.WARN.Printf("Could not get LastMessageID: %+v", err)
@@ -218,8 +238,7 @@ func (rm *ReceptionManager) receiveMessagesFromGateway(session user.Session,
 			// So, we should retrieve it from the gateway.
 			newMessage, err := rm.Comms.SendGetMessage(receiveGateway,
 				&pb.ClientRequest{
-					UserID: session.GetCurrentUser().User.
-						Bytes(),
+					UserID:        userData.ThisUser.User.Bytes(),
 					LastMessageID: messageID,
 				})
 			if err != nil {
diff --git a/io/send.go b/io/send.go
index ff3146ae6b6b34d6bcda0770e454768cb445e97f..53fadf2f9e1252d16370064fa5e0ab632bdef867 100644
--- a/io/send.go
+++ b/io/send.go
@@ -115,6 +115,12 @@ func (rm *ReceptionManager) send(session user.Session, topology *connect.Circuit
 	cryptoType parse.CryptoType,
 	message *format.Message,
 	rekey bool, transmitGateway *connect.Host) error {
+
+	userData, err := SessionV2.GetUserData()
+	if err != nil {
+		return err
+	}
+
 	// Enable transmission blocking if enabled
 	if rm.blockTransmissions {
 		rm.sendLock.Lock()
@@ -124,6 +130,8 @@ func (rm *ReceptionManager) send(session user.Session, topology *connect.Circuit
 		}()
 	}
 
+	uid := userData.ThisUser.User
+
 	// Check message type
 	if cryptoType == parse.E2E {
 		handleE2ESending(session, message, rekey)
@@ -134,7 +142,8 @@ func (rm *ReceptionManager) send(session user.Session, topology *connect.Circuit
 		}
 		message.Contents.Set(padded)
 		e2e.SetUnencrypted(message)
-		message.SetKeyFP(*format.NewFingerprint(session.GetCurrentUser().User.Marshal()[:32]))
+		fp := format.NewFingerprint(uid.Marshal()[:32])
+		message.SetKeyFP(*fp)
 	}
 	// CMIX Encryption
 	salt := cmix.NewSalt(csprng.Source(&csprng.SystemRNG{}), 32)
@@ -142,7 +151,7 @@ func (rm *ReceptionManager) send(session user.Session, topology *connect.Circuit
 
 	// Construct slot message
 	msgPacket := &pb.Slot{
-		SenderID: session.GetCurrentUser().User.Marshal(),
+		SenderID: uid.Marshal(),
 		PayloadA: encMsg.GetPayloadA(),
 		PayloadB: encMsg.GetPayloadB(),
 		Salt:     salt,
@@ -199,6 +208,11 @@ func handleE2ESending(session user.Session,
 		globals.Log.ERROR.Panic(err)
 	}
 
+	userData, err := SessionV2.GetUserData()
+	if err != nil {
+		globals.Log.FATAL.Panicf("Couldn't get userData: %+v ", err)
+	}
+
 	var key *keyStore.E2EKey
 	var action keyStore.Action
 	// Get KeyManager for this partner
@@ -246,7 +260,7 @@ func handleE2ESending(session user.Session,
 	if action == keyStore.Rekey {
 		// Send RekeyTrigger message to switchboard
 		rekeyMsg := &parse.Message{
-			Sender: session.GetCurrentUser().User,
+			Sender: userData.ThisUser.User,
 			TypedBody: parse.TypedBody{
 				MessageType: int32(cmixproto.Type_REKEY_TRIGGER),
 				Body:        []byte{},
@@ -259,12 +273,12 @@ func handleE2ESending(session user.Session,
 
 	globals.Log.DEBUG.Printf("E2E encrypting message")
 	if rekey {
-		crypto.E2EEncryptUnsafe(session.GetE2EGroup(),
+		crypto.E2EEncryptUnsafe(userData.E2EGrp,
 			key.GetKey(),
 			key.KeyFingerprint(),
 			message)
 	} else {
-		crypto.E2EEncrypt(session.GetE2EGroup(),
+		crypto.E2EEncrypt(userData.E2EGrp,
 			key.GetKey(),
 			key.KeyFingerprint(),
 			message)
diff --git a/rekey/rekey.go b/rekey/rekey.go
index 737c94656efde87f3a7a2b16755e211b5545428f..c20b1a7f41cb060457ce5db93fce2fcb20c1b39b 100644
--- a/rekey/rekey.go
+++ b/rekey/rekey.go
@@ -8,6 +8,7 @@ import (
 	"gitlab.com/elixxir/client/io"
 	"gitlab.com/elixxir/client/keyStore"
 	"gitlab.com/elixxir/client/parse"
+	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
@@ -20,6 +21,7 @@ import (
 )
 
 var session user.Session
+var sessionV2 storage.Session
 var topology *connect.Circuit
 var comms io.Communications
 var transmissionHost *connect.Host
@@ -88,13 +90,15 @@ func (l *rekeyConfirmListener) Hear(msg switchboard.Item, isHeardElsewhere bool,
 }
 
 // InitRekey is called internally by the Login API
-func InitRekey(s user.Session, m io.Communications, t *connect.Circuit, host *connect.Host, rekeyChan2 chan struct{}) {
+func InitRekey(s user.Session, s2 storage.Session, m io.Communications,
+	t *connect.Circuit, host *connect.Host, rekeyChan2 chan struct{}) {
 
 	rekeyTriggerList = rekeyTriggerListener{}
 	rekeyList = rekeyListener{}
 	rekeyConfirmList = rekeyConfirmListener{}
 
 	session = s
+	sessionV2 = s2
 	topology = t
 	comms = m
 	transmissionHost = host
@@ -102,7 +106,12 @@ func InitRekey(s user.Session, m io.Communications, t *connect.Circuit, host *co
 	rekeyChan = rekeyChan2
 	l := session.GetSwitchboard()
 
-	l.Register(s.GetCurrentUser().User,
+	userData, err := s2.GetUserData()
+	if err != nil {
+		globals.Log.FATAL.Panicf("could not load user data: %+v", err)
+	}
+
+	l.Register(userData.ThisUser.User,
 		int32(cmixproto.Type_REKEY_TRIGGER),
 		&rekeyTriggerList)
 	// TODO(nen) Wouldn't it be possible to register these listeners based
@@ -129,7 +138,12 @@ const (
 
 func rekeyProcess(rt rekeyType, partner *id.ID, data []byte) error {
 	rkm := session.GetRekeyManager()
-	e2egrp := session.GetE2EGroup()
+	userData, err := sessionV2.GetUserData()
+	if err != nil {
+		return fmt.Errorf("could not load user data: %+v", err)
+	}
+
+	e2egrp := userData.E2EGrp
 
 	// Error handling according to Rekey Message Type
 	var ctx *keyStore.RekeyContext
@@ -215,7 +229,7 @@ func rekeyProcess(rt rekeyType, partner *id.ID, data []byte) error {
 			partner, false,
 			numKeys, keysTTL, params.NumRekeys)
 		// Generate Receive Keys
-		e2ekeys := km.GenerateKeys(e2egrp, session.GetCurrentUser().User)
+		e2ekeys := km.GenerateKeys(e2egrp, userData.ThisUser.User)
 		session.GetKeyStore().AddRecvManager(km)
 		session.GetKeyStore().AddReceiveKeysByFingerprint(e2ekeys)
 
@@ -235,7 +249,7 @@ func rekeyProcess(rt rekeyType, partner *id.ID, data []byte) error {
 				partner, true,
 				numKeys, keysTTL, params.NumRekeys)
 			// Generate Send Keys
-			km.GenerateKeys(e2egrp, session.GetCurrentUser().User)
+			km.GenerateKeys(e2egrp, userData.ThisUser.User)
 			session.GetKeyStore().AddSendManager(km)
 			// Remove RekeyContext
 			rkm.DeleteCtx(partner)
diff --git a/rekey/rekey_test.go b/rekey/rekey_test.go
index 43d430ec0ef9307c757b37ca737b622bcba876f5..dc007afaa088a33bd5706f86d4a3ba182ff1e413 100644
--- a/rekey/rekey_test.go
+++ b/rekey/rekey_test.go
@@ -8,7 +8,9 @@ import (
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/keyStore"
 	"gitlab.com/elixxir/client/parse"
+	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/client/userRegistry"
 	"gitlab.com/elixxir/crypto/csprng"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/diffieHellman"
@@ -57,9 +59,9 @@ func (d *dummyMessaging) MessageReceiver(session user.Session,
 func TestMain(m *testing.M) {
 
 	grp, e2eGrp := getGroups()
-	user.InitUserRegistry(grp)
+	userRegistry.InitUserRegistry(grp)
 	rng := csprng.NewSystemRNG()
-	u := &user.User{
+	u := &storage.User{
 		User:     new(id.ID),
 		Username: "Bernie",
 	}
@@ -78,19 +80,32 @@ func TestMain(m *testing.M) {
 	privateKeyRSA, _ := rsa.GenerateKey(rng, 768)
 	publicKeyRSA := rsa.PublicKey{PublicKey: privateKeyRSA.PublicKey}
 
-	session := user.NewSession(&globals.RamStorage{},
-		u, &publicKeyRSA, privateKeyRSA, myPubKeyCyclicCMIX,
-		myPrivKeyCyclicCMIX, myPubKeyCyclicE2E, myPrivKeyCyclicE2E, make([]byte, 1),
-		grp, e2eGrp, "password")
+	session := user.NewSession(&globals.RamStorage{}, "password")
 	ListenCh = make(chan []byte, 100)
 	fakeComm := &dummyMessaging{
 		listener: ListenCh,
 	}
 
+	sessionV2 := storage.InitTestingSession(m)
+
+	userData := &storage.UserData{
+		ThisUser:         u,
+		RSAPrivateKey:    privateKeyRSA,
+		RSAPublicKey:     &publicKeyRSA,
+		CMIXDHPrivateKey: myPrivKeyCyclicCMIX,
+		CMIXDHPublicKey:  myPubKeyCyclicCMIX,
+		E2EDHPrivateKey:  myPrivKeyCyclicE2E,
+		E2EDHPublicKey:   myPubKeyCyclicE2E,
+		CmixGrp:          grp,
+		E2EGrp:           e2eGrp,
+		Salt:             make([]byte, 1),
+	}
+	sessionV2.CommitUserData(userData)
+
 	rekeyChan2 := make(chan struct{}, 50)
 	nodeID := new(id.ID)
 	nodeID.SetType(id.Node)
-	InitRekey(session, fakeComm, connect.NewCircuit([]*id.ID{nodeID}), nil, rekeyChan2)
+	InitRekey(session, *sessionV2, fakeComm, connect.NewCircuit([]*id.ID{nodeID}), nil, rekeyChan2)
 
 	// Create E2E relationship with partner
 	// Generate baseKey
@@ -140,10 +155,11 @@ func TestRekeyTrigger(t *testing.T) {
 	binary.BigEndian.PutUint64(partnerID[:], 12)
 	partnerID.SetType(id.User)
 	km := session.GetKeyStore().GetRecvManager(partnerID)
+	userData, _ := sessionV2.GetUserData()
 	partnerPubKey := km.GetPubKey()
 	// Test receiving a RekeyTrigger message
 	msg := &parse.Message{
-		Sender: session.GetCurrentUser().User,
+		Sender: userData.ThisUser.User,
 		TypedBody: parse.TypedBody{
 			MessageType: int32(cmixproto.Type_REKEY_TRIGGER),
 			Body:        partnerPubKey.Bytes(),
@@ -160,7 +176,7 @@ func TestRekeyTrigger(t *testing.T) {
 	// Get new PubKey from Rekey message and confirm value matches
 	// with PubKey created from privKey in Rekey Context
 	value := <-ListenCh
-	grpE2E := session.GetE2EGroup()
+	grpE2E := userData.E2EGrp
 	actualPubKey := grpE2E.NewIntFromBytes(value)
 	privKey := session.GetRekeyManager().GetCtx(partnerID).PrivKey
 	fmt.Println("privKey: ", privKey.Text(16))
@@ -176,7 +192,7 @@ func TestRekeyTrigger(t *testing.T) {
 
 	// Check that trying to send another rekeyTrigger message returns an error
 	msg = &parse.Message{
-		Sender: session.GetCurrentUser().User,
+		Sender: userData.ThisUser.User,
 		TypedBody: parse.TypedBody{
 			MessageType: int32(cmixproto.Type_REKEY_TRIGGER),
 			Body:        partnerPubKey.Bytes(),
@@ -199,6 +215,7 @@ func TestRekeyConfirm(t *testing.T) {
 	partnerID.SetType(id.User)
 	rekeyCtx := session.GetRekeyManager().GetCtx(partnerID)
 	baseKey := rekeyCtx.BaseKey
+	userData, _ := sessionV2.GetUserData()
 	// Test receiving a RekeyConfirm message with wrong H(baseKey)
 	msg := &parse.Message{
 		Sender: partnerID,
@@ -207,7 +224,7 @@ func TestRekeyConfirm(t *testing.T) {
 			Body:        baseKey.Bytes(),
 		},
 		InferredType: parse.None,
-		Receiver:     session.GetCurrentUser().User,
+		Receiver:     userData.ThisUser.User,
 	}
 	session.GetSwitchboard().Speak(msg)
 	time.Sleep(time.Second)
@@ -226,7 +243,7 @@ func TestRekeyConfirm(t *testing.T) {
 			Body:        h.Sum(nil),
 		},
 		InferredType: parse.None,
-		Receiver:     session.GetCurrentUser().User,
+		Receiver:     userData.ThisUser.User,
 	}
 	session.GetSwitchboard().Speak(msg)
 	time.Sleep(time.Second)
@@ -237,7 +254,7 @@ func TestRekeyConfirm(t *testing.T) {
 
 	// Confirm that user Private key in Send Key Manager
 	// differs from the one stored in session
-	if session.GetE2EDHPrivateKey().GetLargeInt().Cmp(
+	if userData.E2EDHPrivateKey.GetLargeInt().Cmp(
 		session.GetKeyStore().GetSendManager(partnerID).
 			GetPrivKey().GetLargeInt()) == 0 {
 		t.Errorf("PrivateKey remained unchanged after Outgoing Rekey!")
@@ -252,7 +269,7 @@ func TestRekeyConfirm(t *testing.T) {
 			Body:        h.Sum(nil),
 		},
 		InferredType: parse.None,
-		Receiver:     session.GetCurrentUser().User,
+		Receiver:     userData.ThisUser.User,
 	}
 	session.GetSwitchboard().Speak(msg)
 	time.Sleep(time.Second)
@@ -268,6 +285,7 @@ func TestRekey(t *testing.T) {
 	binary.BigEndian.PutUint64(partnerID[:], 12)
 	partnerID.SetType(id.User)
 	km := session.GetKeyStore().GetSendManager(partnerID)
+	userData, _ := sessionV2.GetUserData()
 	// Generate new partner public key
 	_, grp := getGroups()
 	privKey := grp.RandomCoprime(grp.NewMaxInt())
@@ -280,7 +298,7 @@ func TestRekey(t *testing.T) {
 			Body:        pubKey.Bytes(),
 		},
 		InferredType: parse.Rekey,
-		Receiver:     session.GetCurrentUser().User,
+		Receiver:     userData.ThisUser.User,
 	}
 	session.GetSwitchboard().Speak(msg)
 
@@ -307,14 +325,14 @@ func TestRekey(t *testing.T) {
 	// Confirm that keys rotated properly in RekeyManager
 	rkm := session.GetRekeyManager()
 	keys := rkm.GetKeys(partnerID)
-	if keys.CurrPubKey.GetLargeInt().Cmp(session.GetE2EDHPublicKey().GetLargeInt()) == 0 {
+	if keys.CurrPubKey.GetLargeInt().Cmp(userData.E2EDHPublicKey.GetLargeInt()) == 0 {
 		t.Errorf("Own publicKey didn't update properly after both parties rekeys")
 
 	}
 	if keys.CurrPrivKey.GetLargeInt().
-		Cmp(session.GetE2EDHPrivateKey().GetLargeInt()) == 0 {
+		Cmp(userData.E2EDHPrivateKey.GetLargeInt()) == 0 {
 		t.Errorf("Own PrivateKey didn't update properly after both parties rekeys")
-		t.Errorf("%s\n%s", keys.CurrPrivKey.GetLargeInt().Text(16), session.GetE2EDHPrivateKey().GetLargeInt().Text(16))
+		t.Errorf("%s\n%s", keys.CurrPrivKey.GetLargeInt().Text(16), userData.E2EDHPrivateKey.GetLargeInt().Text(16))
 	}
 
 	if keys.CurrPubKey.GetLargeInt().
@@ -331,10 +349,11 @@ func TestRekey_Errors(t *testing.T) {
 	km := session.GetKeyStore().GetRecvManager(partnerID)
 	partnerPubKey := km.GetPubKey()
 	// Delete RekeyKeys so that RekeyTrigger and rekey error out
+	userData, _ := sessionV2.GetUserData()
 	session.GetRekeyManager().DeleteKeys(partnerID)
 	// Test receiving a RekeyTrigger message
 	msg := &parse.Message{
-		Sender: session.GetCurrentUser().User,
+		Sender: userData.ThisUser.User,
 		TypedBody: parse.TypedBody{
 			MessageType: int32(cmixproto.Type_REKEY_TRIGGER),
 			Body:        partnerPubKey.Bytes(),
@@ -357,7 +376,7 @@ func TestRekey_Errors(t *testing.T) {
 			Body:        []byte{},
 		},
 		InferredType: parse.Rekey,
-		Receiver:     session.GetCurrentUser().User,
+		Receiver:     userData.ThisUser.User,
 	}
 	session.GetSwitchboard().Speak(msg)
 	time.Sleep(time.Second)
diff --git a/user/session.go b/user/session.go
index 89e9bb9d02823a1c4cdf92d1ca8a1ac07b321f77..d01a102c9ab522ba5debbed47b9af0d051b97977 100644
--- a/user/session.go
+++ b/user/session.go
@@ -18,7 +18,6 @@ import (
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/keyStore"
 	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/signature/rsa"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/switchboard"
 	"gitlab.com/xx_network/primitives/id"
@@ -33,17 +32,6 @@ var ErrQuery = errors.New("element not in map")
 
 // Interface for User Session operations
 type Session interface {
-	GetCurrentUser() (currentUser *User)
-	GetRSAPrivateKey() *rsa.PrivateKey
-	GetRSAPublicKey() *rsa.PublicKey
-	GetCMIXDHPrivateKey() *cyclic.Int
-	GetCMIXDHPublicKey() *cyclic.Int
-	GetE2EDHPrivateKey() *cyclic.Int
-	GetE2EDHPublicKey() *cyclic.Int
-	GetCmixGroup() *cyclic.Group
-	GetE2EGroup() *cyclic.Group
-	GetLastMessageID() string
-	SetLastMessageID(id string)
 	StoreSession() error
 	Immolate() error
 	UpsertMap(key string, element interface{}) error
@@ -59,10 +47,8 @@ type Session interface {
 	GetRegistrationValidationSignature() []byte
 	AppendGarbledMessage(messages ...*format.Message)
 	PopGarbledMessages() []*format.Message
-	GetSalt() []byte
 	SetRegState(rs uint32) error
 	GetRegState() uint32
-	ChangeUsername(string) error
 	StorageIsEmpty() bool
 	GetContactByValue(string) (*id.ID, []byte)
 	StoreContactByValue(string, *id.ID, []byte)
@@ -79,29 +65,10 @@ type NodeKeys struct {
 
 // Creates a new Session interface for registration
 func NewSession(store globals.Storage,
-	u *User,
-	publicKeyRSA *rsa.PublicKey,
-	privateKeyRSA *rsa.PrivateKey,
-	cmixPublicKeyDH *cyclic.Int,
-	cmixPrivateKeyDH *cyclic.Int,
-	e2ePublicKeyDH *cyclic.Int,
-	e2ePrivateKeyDH *cyclic.Int,
-	salt []byte,
-	cmixGrp, e2eGrp *cyclic.Group,
 	password string) Session {
 	regState := uint32(KeyGenComplete)
 	// With an underlying Session data structure
 	return Session(&SessionObj{
-		NodeKeys:            make(map[id.ID]NodeKeys),
-		CurrentUser:         u,
-		RSAPublicKey:        publicKeyRSA,
-		RSAPrivateKey:       privateKeyRSA,
-		CMIXDHPublicKey:     cmixPublicKeyDH,
-		CMIXDHPrivateKey:    cmixPrivateKeyDH,
-		E2EDHPublicKey:      e2ePublicKeyDH,
-		E2EDHPrivateKey:     e2ePrivateKeyDH,
-		CmixGrp:             cmixGrp,
-		E2EGrp:              e2eGrp,
 		InterfaceMap:        make(map[string]interface{}),
 		KeyMaps:             keyStore.NewStore(),
 		RekeyManager:        keyStore.NewRekeyManager(),
@@ -109,7 +76,6 @@ func NewSession(store globals.Storage,
 		listeners:           switchboard.NewSwitchboard(),
 		quitReceptionRunner: make(chan struct{}),
 		password:            password,
-		Salt:                salt,
 		RegState:            &regState,
 		storageLocation:     globals.LocationA,
 		ContactsByValue:     make(map[string]SearchedUserRecord),
@@ -156,9 +122,6 @@ func LoadSession(store globals.Storage, password string) (Session, error) {
 
 	session.storageLocation = loadLocation
 
-	// Reconstruct Key maps
-	session.KeyMaps.ReconstructKeys(session.E2EGrp,
-		session.CurrentUser.User)
 	// Create switchboard
 	session.listeners = switchboard.NewSwitchboard()
 	// Create quit channel for reception runner
@@ -168,10 +131,6 @@ func LoadSession(store globals.Storage, password string) (Session, error) {
 	session.store = store
 	session.password = password
 
-	if session.NodeKeys == nil {
-		session.NodeKeys = make(map[id.ID]NodeKeys)
-	}
-
 	return &session, nil
 }
 
@@ -239,20 +198,6 @@ func processSessionWrapper(sessionGob []byte, password string) (*SessionStorageW
 // When adding to this structure, ALWAYS ALWAYS
 // consider if you want the data to be in the session file
 type SessionObj struct {
-	// Currently authenticated user
-	CurrentUser *User
-
-	NodeKeys         map[id.ID]NodeKeys
-	RSAPrivateKey    *rsa.PrivateKey
-	RSAPublicKey     *rsa.PublicKey
-	CMIXDHPrivateKey *cyclic.Int
-	CMIXDHPublicKey  *cyclic.Int
-	E2EDHPrivateKey  *cyclic.Int
-	E2EDHPublicKey   *cyclic.Int
-	CmixGrp          *cyclic.Group
-	E2EGrp           *cyclic.Group
-	Salt             []byte
-
 	// Last received message ID. Check messages after this on the gateway.
 	LastMessageID string
 
@@ -325,13 +270,6 @@ type SearchedUserRecord struct {
 	Pk []byte
 }
 
-func (s *SessionObj) GetLastMessageID() string {
-	s.LockStorage()
-	defer s.UnlockStorage()
-
-	return s.LastMessageID
-}
-
 func (s *SessionObj) StorageIsEmpty() bool {
 	s.LockStorage()
 	defer s.UnlockStorage()
@@ -344,14 +282,6 @@ func (s *SessionObj) SetLastMessageID(id string) {
 	s.UnlockStorage()
 }
 
-func (s *SessionObj) GetSalt() []byte {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	salt := make([]byte, len(s.Salt))
-	copy(salt, s.Salt)
-	return salt
-}
-
 //RegisterPermissioningSignature sets sessions registration signature and
 // sets the regState to reflect that registering with permissioning is complete
 // Returns an error if unable to set the regState
@@ -373,76 +303,12 @@ func (s *SessionObj) RegisterPermissioningSignature(sig []byte) error {
 	return err
 }
 
-func (s *SessionObj) GetRSAPrivateKey() *rsa.PrivateKey {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.RSAPrivateKey
-}
-
-func (s *SessionObj) GetRSAPublicKey() *rsa.PublicKey {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.RSAPublicKey
-}
-
-func (s *SessionObj) GetCMIXDHPrivateKey() *cyclic.Int {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.CMIXDHPrivateKey
-}
-
-func (s *SessionObj) GetCMIXDHPublicKey() *cyclic.Int {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.CMIXDHPublicKey
-}
-
-func (s *SessionObj) GetE2EDHPrivateKey() *cyclic.Int {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.E2EDHPrivateKey
-}
-
-func (s *SessionObj) GetE2EDHPublicKey() *cyclic.Int {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.E2EDHPublicKey
-}
-
-func (s *SessionObj) GetCmixGroup() *cyclic.Group {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.CmixGrp
-}
-
 func (s *SessionObj) GetRegistrationValidationSignature() []byte {
 	s.LockStorage()
 	defer s.UnlockStorage()
 	return s.RegValidationSignature
 }
 
-func (s *SessionObj) GetE2EGroup() *cyclic.Group {
-	s.LockStorage()
-	defer s.UnlockStorage()
-	return s.E2EGrp
-}
-
-// Return a copy of the current user
-func (s *SessionObj) GetCurrentUser() (currentUser *User) {
-	// This is where it deadlocks
-	s.LockStorage()
-	defer s.UnlockStorage()
-	if s.CurrentUser != nil {
-		// Explicit deep copy
-		currentUser = &User{
-			User:     s.CurrentUser.User,
-			Username: s.CurrentUser.Username,
-			Precan:   s.CurrentUser.Precan,
-		}
-	}
-	return currentUser
-}
-
 func (s *SessionObj) GetRegState() uint32 {
 	return atomic.LoadUint32(s.RegState)
 }
@@ -456,12 +322,6 @@ func (s *SessionObj) SetRegState(rs uint32) error {
 	return nil
 }
 
-func (s *SessionObj) ChangeUsername(username string) error {
-
-	s.CurrentUser.Username = username
-	return nil
-}
-
 type SessionStorageWrapper struct {
 	Version   uint32
 	Timestamp time.Time
diff --git a/user/session_test.go b/user/session_test.go
index 08176cf53d877d5d028ca4499f5cc3506a68ca4b..564faa9871d2cda280bc1c3f57f9e46ed41e77a1 100644
--- a/user/session_test.go
+++ b/user/session_test.go
@@ -7,15 +7,11 @@
 package user
 
 import (
-	"bytes"
 	"crypto/sha256"
-	"encoding/gob"
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/large"
-	"gitlab.com/elixxir/crypto/signature/rsa"
 	"gitlab.com/elixxir/primitives/format"
-	"gitlab.com/xx_network/primitives/id"
 	"math/rand"
 	"reflect"
 	"testing"
@@ -27,33 +23,12 @@ func TestUserSession(t *testing.T) {
 
 	pass := 0
 
-	u := new(User)
-	// This is 65 so you can see the letter A in the gob if you need to make
-	// sure that the gob contains the user ID
-	UID := uint64(65)
-
-	u.User = id.NewIdFromUInt(UID, id.User, t)
-	u.Username = "Mario"
-
 	// Storage
 	storage := &globals.RamStorage{}
 
 	rng := rand.New(rand.NewSource(42))
-	privateKey, _ := rsa.GenerateKey(rng, 768)
-	publicKey := rsa.PublicKey{PublicKey: privateKey.PublicKey}
-
-	cmixGrp, e2eGrp := getGroups()
-
-	privateKeyDH := cmixGrp.RandomCoprime(cmixGrp.NewInt(1))
-	publicKeyDH := cmixGrp.ExpG(privateKeyDH, cmixGrp.NewInt(1))
-
-	privateKeyDHE2E := e2eGrp.RandomCoprime(e2eGrp.NewInt(1))
-	publicKeyDHE2E := e2eGrp.ExpG(privateKeyDHE2E, e2eGrp.NewInt(1))
 
-	ses := NewSession(storage,
-		u, &publicKey, privateKey, publicKeyDH, privateKeyDH,
-		publicKeyDHE2E, privateKeyDHE2E, make([]byte, 1), cmixGrp, e2eGrp,
-		"password")
+	ses := NewSession(storage, "password")
 
 	regSignature := make([]byte, 768)
 	rng.Read(regSignature)
@@ -64,8 +39,6 @@ func TestUserSession(t *testing.T) {
 			err.Error())
 	}
 
-	ses.SetLastMessageID("totally unique ID")
-
 	err = ses.StoreSession()
 
 	if err != nil {
@@ -85,29 +58,6 @@ func TestUserSession(t *testing.T) {
 		pass++
 	}
 
-	if ses.GetLastMessageID() != "totally unique ID" {
-		t.Errorf("Last message ID should have been stored " +
-			"and loaded")
-	} else {
-		pass++
-	}
-
-	ses.SetLastMessageID("test")
-
-	if ses.GetLastMessageID() != "test" {
-		t.Errorf("Last message ID not set correctly with" +
-			" SetLastMessageID!")
-	} else {
-		pass++
-	}
-
-	//TODO: FIX THIS?
-	if ses.GetRSAPrivateKey() == nil {
-		t.Errorf("Error: Private Keys not set correctly!")
-	} else {
-		pass++
-	}
-
 	err = ses.UpsertMap("test", 5)
 
 	if err != nil {
@@ -166,126 +116,19 @@ func TestUserSession(t *testing.T) {
 	}
 }
 
-func TestSessionObj_DeleteContact(t *testing.T) {
-	u := new(User)
-	// This is 65 so you can see the letter A in the gob if you need to make
-	// sure that the gob contains the user ID
-	UID := uint64(65)
-
-	u.User = id.NewIdFromUInt(UID, id.User, t)
-	u.Username = "Mario"
-
-	// Storage
-	storage := &globals.RamStorage{}
-
-	rng := rand.New(rand.NewSource(42))
-	privateKey, _ := rsa.GenerateKey(rng, 768)
-	publicKey := rsa.PublicKey{PublicKey: privateKey.PublicKey}
-
-	cmixGrp, e2eGrp := getGroups()
-
-	privateKeyDH := cmixGrp.RandomCoprime(cmixGrp.NewInt(1))
-	publicKeyDH := cmixGrp.ExpG(privateKeyDH, cmixGrp.NewInt(1))
-
-	privateKeyDHE2E := e2eGrp.RandomCoprime(e2eGrp.NewInt(1))
-	publicKeyDHE2E := e2eGrp.ExpG(privateKeyDHE2E, e2eGrp.NewInt(1))
-
-	ses := NewSession(storage,
-		u, &publicKey, privateKey, publicKeyDH, privateKeyDH,
-		publicKeyDHE2E, privateKeyDHE2E, make([]byte, 1), cmixGrp, e2eGrp,
-		"password")
-
-	regSignature := make([]byte, 768)
-	rng.Read(regSignature)
-
-	err := ses.RegisterPermissioningSignature(regSignature)
-	if err != nil {
-		t.Errorf("failure in setting register up for permissioning: %s",
-			err.Error())
-	}
-
-	testContact := id.NewIdFromString("test", id.User, t)
-	ses.StoreContactByValue("test", testContact, []byte("test"))
-
-	_, err = ses.DeleteContact(testContact)
-	if err != nil {
-		t.Errorf("Failed to delete contact: %+v", err)
-	}
-}
-
-func TestGetPubKey(t *testing.T) {
-	u := new(User)
-	UID := id.NewIdFromUInt(1, id.User, t)
-
-	u.User = UID
-	u.Username = "Mario"
-
-	rng := rand.New(rand.NewSource(42))
-	privateKey, _ := rsa.GenerateKey(rng, 768)
-	publicKey := rsa.PublicKey{PublicKey: privateKey.PublicKey}
-
-	cmixGrp, e2eGrp := getGroups()
-
-	privateKeyDH := cmixGrp.RandomCoprime(cmixGrp.NewInt(1))
-	publicKeyDH := cmixGrp.ExpG(privateKeyDH, cmixGrp.NewInt(1))
-
-	privateKeyDHE2E := e2eGrp.RandomCoprime(e2eGrp.NewInt(1))
-	publicKeyDHE2E := e2eGrp.ExpG(privateKeyDHE2E, e2eGrp.NewInt(1))
-
-	ses := NewSession(&globals.RamStorage{},
-		u, &publicKey, privateKey, publicKeyDH, privateKeyDH,
-		publicKeyDHE2E, privateKeyDHE2E, make([]byte, 1), cmixGrp, e2eGrp,
-		"password")
-
-	regSignature := make([]byte, 768)
-	rng.Read(regSignature)
-
-	err := ses.RegisterPermissioningSignature(regSignature)
-	if err != nil {
-		t.Errorf("failure in setting register up for permissioning: %s",
-			err.Error())
-	}
-
-	pubKey := *ses.GetRSAPublicKey()
-	if !reflect.DeepEqual(pubKey, publicKey) {
-		t.Errorf("Public key not returned correctly!")
-	}
-}
-
 //Tests the isEmpty function before and after StoreSession
 func TestSessionObj_StorageIsEmpty(t *testing.T) {
-	// Generate all the values needed for a session
-	u := new(User)
-	// This is 65 so you can see the letter A in the gob if you need to make
-	// sure that the gob contains the user ID
-	UID := uint64(65)
-
-	u.User = id.NewIdFromUInt(UID, id.User, t)
-	u.Username = "Mario"
-
 	// Storage
 	storage := &globals.RamStorage{}
 
 	//Keys
 	rng := rand.New(rand.NewSource(42))
-	privateKey, _ := rsa.GenerateKey(rng, 768)
-	publicKey := rsa.PublicKey{PublicKey: privateKey.PublicKey}
-	cmixGrp, e2eGrp := getGroups()
-	privateKeyDH := cmixGrp.RandomCoprime(cmixGrp.NewInt(1))
-	publicKeyDH := cmixGrp.ExpG(privateKeyDH, cmixGrp.NewInt(1))
-	privateKeyDHE2E := e2eGrp.RandomCoprime(e2eGrp.NewInt(1))
-	publicKeyDHE2E := e2eGrp.ExpG(privateKeyDHE2E, e2eGrp.NewInt(1))
-
-	ses := NewSession(storage,
-		u, &publicKey, privateKey, publicKeyDH, privateKeyDH,
-		publicKeyDHE2E, privateKeyDHE2E, make([]byte, 1), cmixGrp, e2eGrp,
-		"password")
+
+	ses := NewSession(storage, "password")
 
 	regSignature := make([]byte, 768)
 	rng.Read(regSignature)
 
-	ses.SetLastMessageID("totally unique ID")
-
 	//Test that the session is empty before the StoreSession call
 	if !ses.StorageIsEmpty() {
 		t.Errorf("session should be empty before the StoreSession call")
@@ -302,121 +145,6 @@ func TestSessionObj_StorageIsEmpty(t *testing.T) {
 
 }
 
-// GetContactByValue happy path
-func TestSessionObj_GetContactByValue(t *testing.T) {
-	// Generate all the values needed for a session
-	u := new(User)
-	// This is 65 so you can see the letter A in the gob if you need to make
-	// sure that the gob contains the user ID
-	UID := uint64(65)
-
-	u.User = id.NewIdFromUInt(UID, id.User, t)
-	u.Username = "Mario"
-
-	// Storage
-	storage := &globals.RamStorage{}
-
-	//Keys
-	rng := rand.New(rand.NewSource(42))
-	privateKey, _ := rsa.GenerateKey(rng, 768)
-	publicKey := rsa.PublicKey{PublicKey: privateKey.PublicKey}
-	cmixGrp, e2eGrp := getGroups()
-	privateKeyDH := cmixGrp.RandomCoprime(cmixGrp.NewInt(1))
-	publicKeyDH := cmixGrp.ExpG(privateKeyDH, cmixGrp.NewInt(1))
-	privateKeyDHE2E := e2eGrp.RandomCoprime(e2eGrp.NewInt(1))
-	publicKeyDHE2E := e2eGrp.ExpG(privateKeyDHE2E, e2eGrp.NewInt(1))
-
-	ses := NewSession(storage,
-		u, &publicKey, privateKey, publicKeyDH, privateKeyDH,
-		publicKeyDHE2E, privateKeyDHE2E, make([]byte, 1), cmixGrp, e2eGrp,
-		"password")
-
-	regSignature := make([]byte, 768)
-	rng.Read(regSignature)
-
-	err := ses.RegisterPermissioningSignature(regSignature)
-	if err != nil {
-		t.Errorf("failure in setting register up for permissioning: %s",
-			err.Error())
-	}
-
-	userId := id.NewIdFromBytes([]byte("test"), t)
-
-	ses.StoreContactByValue("value", userId, []byte("test"))
-
-	observedUser, observedPk := ses.GetContactByValue("value")
-
-	if bytes.Compare([]byte("test"), observedPk) != 0 {
-		t.Errorf("Failed to retieve public key using GetContactByValue; "+
-			"Expected: %+v\n\tRecieved: %+v", privateKey.PublicKey.N.Bytes(), observedPk)
-	}
-
-	if !observedUser.Cmp(userId) {
-		t.Errorf("Failed to retrieve user using GetContactByValue;"+
-			"Expected: %+v\n\tRecieved: %+v", u.User, observedUser)
-	}
-}
-
-func TestGetPrivKey(t *testing.T) {
-	u := new(User)
-	UID := id.NewIdFromUInt(1, id.User, t)
-
-	u.User = UID
-	u.Username = "Mario"
-
-	rng := rand.New(rand.NewSource(42))
-	privateKey, _ := rsa.GenerateKey(rng, 768)
-	publicKey := rsa.PublicKey{PublicKey: privateKey.PublicKey}
-
-	cmixGrp, e2eGrp := getGroups()
-
-	privateKeyDH := cmixGrp.RandomCoprime(cmixGrp.NewInt(1))
-	publicKeyDH := cmixGrp.ExpG(privateKeyDH, cmixGrp.NewInt(1))
-
-	privateKeyDHE2E := e2eGrp.RandomCoprime(e2eGrp.NewInt(1))
-	publicKeyDHE2E := e2eGrp.ExpG(privateKeyDHE2E, e2eGrp.NewInt(1))
-
-	ses := NewSession(&globals.RamStorage{},
-		u, &publicKey, privateKey, publicKeyDH, privateKeyDH,
-		publicKeyDHE2E, privateKeyDHE2E, make([]byte, 1), cmixGrp, e2eGrp,
-		"password")
-
-	regSignature := make([]byte, 768)
-	rng.Read(regSignature)
-
-	err := ses.RegisterPermissioningSignature(regSignature)
-	if err != nil {
-		t.Errorf("failure in setting register up for permissioning: %s",
-			err.Error())
-	}
-
-	privKey := ses.GetRSAPrivateKey()
-	if !reflect.DeepEqual(*privKey, *privateKey) {
-		t.Errorf("Private key is not returned correctly!")
-	}
-}
-
-func TestBruntString(t *testing.T) {
-	// Generate a new user and record the pointer to the nick
-	u := new(User)
-	u.Username = "Mario"
-	preBurnPointer := &u.Username
-
-	// Burn the string and record the pointer to the nick
-	u.Username = burntString(len(u.Username))
-	postBurnPointer := &u.Username
-
-	// Check the nick is not the same as before
-	if u.Username == "Mario" {
-		t.Errorf("String was not burnt")
-	}
-
-	// Check the pointer is the same (otherwise it wasn't overwritten)
-	if preBurnPointer != postBurnPointer {
-		t.Errorf("Pointer values are not the same")
-	}
-}
-
 func getGroups() (*cyclic.Group, *cyclic.Group) {
 
 	cmixGrp := cyclic.NewGroup(
@@ -456,9 +184,7 @@ func getGroups() (*cyclic.Group, *cyclic.Group) {
 // Tests that AppendGarbledMessage properly appends an array of messages by
 // testing that the final buffer matches the values appended.
 func TestSessionObj_AppendGarbledMessage(t *testing.T) {
-	session := NewSession(nil, nil, nil, nil,
-		nil, nil, nil,
-		nil, nil, nil, nil, "")
+	session := NewSession(nil, "")
 	msgs := GenerateTestMessages(10)
 
 	session.AppendGarbledMessage(msgs...)
@@ -473,9 +199,7 @@ func TestSessionObj_AppendGarbledMessage(t *testing.T) {
 // Tests that PopGarbledMessages returns the correct data and that the buffer
 // is cleared.
 func TestSessionObj_PopGarbledMessages(t *testing.T) {
-	session := NewSession(nil, nil, nil, nil,
-		nil, nil, nil,
-		nil, nil, nil, nil, "")
+	session := NewSession(nil, "")
 	msgs := GenerateTestMessages(10)
 
 	session.(*SessionObj).garbledMessages = msgs
@@ -548,51 +272,3 @@ func GenerateTestMessages(size int) []*format.Message {
 
 	return msgs
 }
-
-// Happy path
-func TestConvertSessionV1toV2(t *testing.T) {
-	u := new(User)
-	UID := id.NewIdFromUInt(1, id.Node, t)
-
-	u.User = UID
-	u.Username = "Bernie"
-
-	session := NewSession(nil, u, nil, nil,
-		nil, nil, nil,
-		nil, nil, nil, nil, "")
-	var sessionBuffer bytes.Buffer
-
-	enc := gob.NewEncoder(&sessionBuffer)
-
-	err := enc.Encode(session)
-	if err != nil {
-		t.Errorf("Failed to getSessionData: %+v", err)
-	}
-
-	storageWrapper := &SessionStorageWrapper{Version: 1, Session: sessionBuffer.Bytes()}
-	newSession, err := ConvertSessionV1toV2(storageWrapper)
-	if err != nil {
-		t.Errorf("Failed conversion: %+v", err)
-	}
-
-	if newSession.Version != SessionVersion {
-		t.Errorf("ConvertSessionV1toV2 should modify version number")
-	}
-
-}
-
-// Error path: Pass in an improper session
-func TestConvertSessionV1toV2_Error(t *testing.T) {
-	// Pass in an improper session
-	var sessionBuffer bytes.Buffer
-
-	_ = gob.NewEncoder(&sessionBuffer)
-
-	storageWrapper := &SessionStorageWrapper{Version: 1, Session: sessionBuffer.Bytes()}
-
-	_, err := ConvertSessionV1toV2(storageWrapper)
-	if err == nil {
-		t.Errorf("Failed conversion: %+v", err)
-	}
-
-}
diff --git a/user/sessionv1.go b/user/sessionv1.go
index e6bfcf41666fae2067a9adabfe2beb433108c09f..d1571a8b2ed3e72f535a63048ea3c788f58e2d89 100644
--- a/user/sessionv1.go
+++ b/user/sessionv1.go
@@ -106,24 +106,6 @@ func ConvertSessionV1toV2(inputWrappedSession *SessionStorageWrapper) (*SessionS
 		*sessionV1.RegState = 3000
 	}
 
-	//convert the user object
-	sessionV2.CurrentUser = &User{
-		User:     sessionV1.CurrentUser.User,
-		Username: sessionV1.CurrentUser.Email,
-	}
-
-	//port identical values over
-	sessionV2.NodeKeys = sessionV1.Keys
-	sessionV2.RSAPrivateKey = sessionV1.RSAPrivateKey
-	sessionV2.RSAPublicKey = sessionV1.RSAPublicKey
-	sessionV2.CMIXDHPrivateKey = sessionV1.CMIXDHPrivateKey
-	sessionV2.CMIXDHPublicKey = sessionV1.CMIXDHPublicKey
-	sessionV2.E2EDHPrivateKey = sessionV1.E2EDHPrivateKey
-	sessionV2.E2EDHPublicKey = sessionV1.E2EDHPublicKey
-	sessionV2.CmixGrp = sessionV1.CmixGrp
-	sessionV2.E2EGrp = sessionV1.E2EGrp
-	sessionV2.Salt = sessionV1.Salt
-	sessionV2.LastMessageID = sessionV1.LastMessageID
 	sessionV2.InterfaceMap = sessionV1.InterfaceMap
 	sessionV2.KeyMaps = sessionV1.KeyMaps
 	sessionV2.RekeyManager = sessionV1.RekeyManager
diff --git a/user/regCode.go b/userRegistry/regCode.go
similarity index 94%
rename from user/regCode.go
rename to userRegistry/regCode.go
index 1914d03a26a27b36f6574c5a3b806b7d6b07d7e4..8cb936dbc06da8ad5eee57a8d7dea88dd2cd63a0 100644
--- a/user/regCode.go
+++ b/userRegistry/regCode.go
@@ -1,4 +1,4 @@
-package user
+package userRegistry
 
 import (
 	"encoding/base32"
diff --git a/user/user.go b/userRegistry/user.go
similarity index 82%
rename from user/user.go
rename to userRegistry/user.go
index e0fd215fafe43556ccdad059dba92d9391ce24b5..88185809eae2a8eb455afeb26c85d73636247fbc 100644
--- a/user/user.go
+++ b/userRegistry/user.go
@@ -4,12 +4,14 @@
 // All rights reserved.                                                        /
 ////////////////////////////////////////////////////////////////////////////////
 
-package user
+package userRegistry
 
 import (
 	"crypto/sha256"
 	"encoding/binary"
 	"gitlab.com/elixxir/client/globals"
+	"gitlab.com/elixxir/client/storage"
+	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/xx_network/primitives/id"
 )
@@ -32,25 +34,25 @@ func InitUserRegistry(grp *cyclic.Group) {
 
 // Interface for User Registry operations
 type Registry interface {
-	NewUser(id *id.ID, nickname string) *User
+	NewUser(id *id.ID, nickname string) *storage.User
 	DeleteUser(id *id.ID)
-	GetUser(id *id.ID) (user *User, ok bool)
-	UpsertUser(user *User)
+	GetUser(id *id.ID) (user *storage.User, ok bool)
+	UpsertUser(user *storage.User)
 	CountUsers() int
 	LookupUser(hid string) (uid *id.ID, ok bool)
-	LookupKeys(uid *id.ID) (*NodeKeys, bool)
+	LookupKeys(uid *id.ID) (*user.NodeKeys, bool)
 }
 
 type UserMap struct {
 	// Map acting as the User Registry containing User -> ID mapping
-	userCollection map[id.ID]*User
+	userCollection map[id.ID]*storage.User
 	// Increments sequentially for User.ID values
 	idCounter uint64
 	// Temporary map acting as a lookup table for demo user registration codes
 	// Key type is string because keys must implement == and []byte doesn't
 	userLookup map[string]*id.ID
 	//Temporary placed to store the keys for each user
-	keysLookup map[id.ID]*NodeKeys
+	keysLookup map[id.ID]*user.NodeKeys
 }
 
 // newRegistry creates a new Registry interface
@@ -58,9 +60,9 @@ func newRegistry(grp *cyclic.Group) Registry {
 	if len(DemoChannelNames) > 10 || len(DemoUserNicks) > 30 {
 		globals.Log.ERROR.Print("Not enough demo users have been hardcoded.")
 	}
-	userUserIdMap := make(map[id.ID]*User)
+	userUserIdMap := make(map[id.ID]*storage.User)
 	userRegCodeMap := make(map[string]*id.ID)
-	nk := make(map[id.ID]*NodeKeys)
+	nk := make(map[id.ID]*user.NodeKeys)
 
 	// Deterministically create NumDemoUsers users
 	// TODO Replace this with real user registration/discovery
@@ -68,8 +70,8 @@ func newRegistry(grp *cyclic.Group) Registry {
 		currentID := new(id.ID)
 		binary.BigEndian.PutUint64(currentID[:], i)
 		currentID.SetType(id.User)
-		newUsr := new(User)
-		nodeKey := new(NodeKeys)
+		newUsr := new(storage.User)
+		nodeKey := new(user.NodeKeys)
 
 		// Generate user parameters
 		newUsr.User = currentID
@@ -116,33 +118,14 @@ func newRegistry(grp *cyclic.Group) Registry {
 		keysLookup: nk})
 }
 
-// Struct representing a User in the system
-type User struct {
-	User     *id.ID
-	Username string
-	Precan   bool
-}
-
-// DeepCopy performs a deep copy of a user and returns a pointer to the new copy
-func (u *User) DeepCopy() *User {
-	if u == nil {
-		return nil
-	}
-	nu := new(User)
-	nu.User = u.User
-	nu.Username = u.Username
-	nu.Precan = u.Precan
-	return nu
-}
-
 // NewUser creates a new User object with default fields and given address.
-func (m *UserMap) NewUser(id *id.ID, username string) *User {
-	return &User{User: id, Username: username}
+func (m *UserMap) NewUser(id *id.ID, username string) *storage.User {
+	return &storage.User{User: id, Username: username}
 }
 
 // GetUser returns a user with the given ID from userCollection
 // and a boolean for whether the user exists
-func (m *UserMap) GetUser(id *id.ID) (user *User, ok bool) {
+func (m *UserMap) GetUser(id *id.ID) (user *storage.User, ok bool) {
 	user, ok = m.userCollection[*id]
 	user = user.DeepCopy()
 	return
@@ -156,7 +139,7 @@ func (m *UserMap) DeleteUser(id *id.ID) {
 
 // UpsertUser inserts given user into userCollection or update the user if it
 // already exists (Upsert operation).
-func (m *UserMap) UpsertUser(user *User) {
+func (m *UserMap) UpsertUser(user *storage.User) {
 	m.userCollection[*user.User] = user
 }
 
@@ -172,7 +155,7 @@ func (m *UserMap) LookupUser(hid string) (*id.ID, bool) {
 }
 
 // LookupKeys returns the keys for the given user from the temporary key map
-func (m *UserMap) LookupKeys(uid *id.ID) (*NodeKeys, bool) {
+func (m *UserMap) LookupKeys(uid *id.ID) (*user.NodeKeys, bool) {
 	nk, t := m.keysLookup[*uid]
 	return nk, t
 }
diff --git a/user/user_test.go b/userRegistry/user_test.go
similarity index 99%
rename from user/user_test.go
rename to userRegistry/user_test.go
index 6f20a4b8c7e823e27ccbecf79145878e56de73bd..9252882b223a9119f4ffdd71308067961a74d286 100644
--- a/user/user_test.go
+++ b/userRegistry/user_test.go
@@ -4,7 +4,7 @@
 // All rights reserved.                                                        /
 ////////////////////////////////////////////////////////////////////////////////
 
-package user
+package userRegistry
 
 import (
 	"crypto/sha256"