diff --git a/api/client.go b/api/client.go
index bedb3a165f787c8fd48b2758970df5d170ab2118..8e09b41f71a745ec4ffd7b69ffe82bcd21714a98 100644
--- a/api/client.go
+++ b/api/client.go
@@ -9,6 +9,7 @@ package api
 import (
 	"bufio"
 	"crypto"
+	"crypto/rand"
 	gorsa "crypto/rsa"
 	"crypto/sha256"
 	"encoding/base64"
@@ -23,8 +24,11 @@ import (
 	"gitlab.com/elixxir/client/parse"
 	"gitlab.com/elixxir/client/rekey"
 	"gitlab.com/elixxir/client/user"
+	"gitlab.com/elixxir/crypto/csprng"
 	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/elixxir/crypto/large"
+	"gitlab.com/elixxir/crypto/registration"
 	"gitlab.com/elixxir/crypto/signature/rsa"
 	"gitlab.com/elixxir/crypto/tls"
 	"gitlab.com/elixxir/primitives/circuit"
@@ -33,6 +37,7 @@ import (
 	"gitlab.com/elixxir/primitives/switchboard"
 	goio "io"
 	"strings"
+	"sync"
 	"time"
 )
 
@@ -447,6 +452,331 @@ type SearchCallback interface {
 	Callback(userID, pubKey []byte, err error)
 }
 
+const SaltSize = 256
+
+// RegisterWithPermissioning registers user with permissioning and returns the
+// User ID.  Returns an error if registration fails.
+func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode, nick, email,
+	password string, privateKeyRSA *rsa.PrivateKey) (*id.User, error) {
+
+	if !preCan && cl.commManager.GetConnectionStatus() != io.Online {
+		return nil, errors.New("Cannot register when disconnected from the network")
+	}
+
+	var err error
+	var u *user.User
+	var UID *id.User
+
+	cl.opStatus(globals.REG_KEYGEN)
+
+	largeIntBits := 16
+
+	cmixGrp := cyclic.NewGroup(
+		large.NewIntFromString(cl.ndf.CMIX.Prime, largeIntBits),
+		large.NewIntFromString(cl.ndf.CMIX.Generator, largeIntBits))
+
+	e2eGrp := cyclic.NewGroup(
+		large.NewIntFromString(cl.ndf.E2E.Prime, largeIntBits),
+		large.NewIntFromString(cl.ndf.E2E.Generator, largeIntBits))
+
+	// Make CMIX keys array
+	nk := make(map[id.Node]user.NodeKeys)
+
+	// GENERATE CLIENT RSA KEYS
+	if privateKeyRSA == nil {
+		privateKeyRSA, err = rsa.GenerateKey(rand.Reader, rsa.DefaultRSABitLen)
+		if err != nil {
+			return nil, err
+		}
+	}
+
+	publicKeyRSA := privateKeyRSA.GetPublic()
+
+	cmixPrivKeyDHByte, err := csprng.GenerateInGroup(cmixGrp.GetPBytes(), 256, csprng.NewSystemRNG())
+
+	if err != nil {
+		return nil, errors.Errorf("Could not generate cmix DH private key: %s", err.Error())
+	}
+
+	cmixPrivateKeyDH := cmixGrp.NewIntFromBytes(cmixPrivKeyDHByte)
+	cmixPublicKeyDH := cmixGrp.ExpG(cmixPrivateKeyDH, cmixGrp.NewMaxInt())
+
+	e2ePrivKeyDHByte, err := csprng.GenerateInGroup(cmixGrp.GetPBytes(), 256, csprng.NewSystemRNG())
+
+	if err != nil {
+		return nil, errors.Errorf("Could not generate e2e DH private key: %s", err.Error())
+	}
+
+	e2ePrivateKeyDH := e2eGrp.NewIntFromBytes(e2ePrivKeyDHByte)
+	e2ePublicKeyDH := e2eGrp.ExpG(e2ePrivateKeyDH, e2eGrp.NewMaxInt())
+
+	// Initialized response from Registration Server
+	regValidationSignature := make([]byte, 0)
+
+	var salt []byte
+
+	// Handle precanned registration
+	if preCan {
+		cl.opStatus(globals.REG_PRECAN)
+		globals.Log.INFO.Printf("Registering precanned user...")
+		u, UID, nk, err = cl.precannedRegister(registrationCode, nick, nk)
+		if err != nil {
+			errMsg := errors.Errorf("Unable to complete precanned registration: %+v", err)
+			return id.ZeroID, errMsg
+		}
+	} else {
+		cl.opStatus(globals.REG_UID_GEN)
+		globals.Log.INFO.Printf("Registering dynamic user...")
+
+		// Generate salt for UserID
+		salt = make([]byte, SaltSize)
+		_, err = csprng.NewSystemRNG().Read(salt)
+		if err != nil {
+			errMsg := errors.Errorf("Register: Unable to generate salt! %s", err)
+			return id.ZeroID, errMsg
+		}
+
+		// Generate UserID by hashing salt and public key
+		UID = registration.GenUserID(publicKeyRSA, salt)
+
+		// If Registration Server is specified, contact it
+		// Only if registrationCode is set
+		globals.Log.INFO.Println("Register: Contacting registration server")
+		if cl.ndf.Registration.Address != "" && registrationCode != "" {
+			cl.opStatus(globals.REG_PERM)
+			regValidationSignature, err = cl.sendRegistrationMessage(registrationCode, publicKeyRSA)
+			if err != nil {
+				err = errors.Errorf("Register: Unable to send registration message: %+v", err)
+				return id.ZeroID, err
+			}
+		}
+		globals.Log.INFO.Println("Register: successfully passed Registration message")
+
+		var actualNick string
+		if nick != "" {
+			actualNick = nick
+		} else {
+			actualNick = base64.StdEncoding.EncodeToString(UID[:])
+		}
+		u = user.Users.NewUser(UID, actualNick)
+		user.Users.UpsertUser(u)
+	}
+
+	cl.opStatus(globals.REG_SECURE_STORE)
+
+	u.Email = email
+
+	// Create the user session
+	newSession := user.NewSession(cl.storage, u, nk, publicKeyRSA,
+		privateKeyRSA, cmixPublicKeyDH, cmixPrivateKeyDH, e2ePublicKeyDH,
+		e2ePrivateKeyDH, salt, cmixGrp, e2eGrp, password, regValidationSignature)
+	cl.opStatus(globals.REG_SAVE)
+
+	//set the registration state
+	err = newSession.SetRegState(user.PermissioningComplete)
+	if err != nil {
+		return id.ZeroID, errors.Wrap(err, "Permissioning Registration "+
+			"Failed")
+	}
+
+	// Store the user session
+	errStore := newSession.StoreSession()
+
+	if errStore != nil {
+		errMsg := errors.Errorf(
+			"Permissioning Register: could not register due to failed session save"+
+				": %s", errStore.Error())
+		return id.ZeroID, errMsg
+	}
+	cl.session = newSession
+	return UID, nil
+}
+
+// RegisterWithUDB uses the account's email to register with the UDB for
+// User discovery.  Must be called after Register and Connect.
+// It will fail if the user has already registered with UDB
+func (cl *Client) RegisterWithUDB(timeout time.Duration) error {
+
+	regState := cl.GetSession().GetRegState()
+
+	if regState != user.PermissioningComplete {
+		return errors.New("Cannot register with UDB when registration " +
+			"state is not PermissioningComplete")
+	}
+
+	status := cl.commManager.GetConnectionStatus()
+	if status == io.Connecting || status == io.Offline {
+		return errors.New("ERROR: could not RegisterWithUDB - connection is either offline or connecting")
+	}
+
+	email := cl.session.GetCurrentUser().Email
+
+	var err error
+
+	if email != "" {
+		globals.Log.INFO.Printf("Registering user as %s with UDB", email)
+
+		valueType := "EMAIL"
+
+		publicKeyBytes := cl.session.GetE2EDHPublicKey().Bytes()
+		err = bots.Register(valueType, email, publicKeyBytes, cl.opStatus, timeout)
+		if err == nil {
+			globals.Log.INFO.Printf("Registered with UDB!")
+		} else {
+			globals.Log.WARN.Printf("Could not register with UDB: %s", err)
+		}
+
+	} else {
+		globals.Log.INFO.Printf("Not registering with UDB because no " +
+			"email found")
+	}
+
+	if err != nil {
+		return errors.Wrap(err, "Could not register with UDB")
+	}
+
+	//set the registration state
+	err = cl.session.SetRegState(user.UDBComplete)
+
+	if err != nil {
+		return errors.Wrap(err, "UDB Registration Failed")
+	}
+
+	errStore := cl.session.StoreSession()
+
+	// FIXME If we have an error here, the session that gets created
+	// doesn't get immolated. Immolation should happen in a deferred
+	//  call instead.
+	if errStore != nil {
+		errMsg := errors.Errorf(
+			"UDB Register: could not register due to failed session save"+
+				": %s", errStore.Error())
+		return errMsg
+	}
+
+	return nil
+}
+
+func (cl *Client) RegisterWithNodes() error {
+	session := cl.GetSession()
+	//Load Cmix keys & group
+	cmixDHPrivKey := session.GetCMIXDHPrivateKey()
+	cmixDHPubKey := session.GetCMIXDHPublicKey()
+	cmixGrp := session.GetCmixGroup()
+
+	//Load the rsa keys
+	rsaPubKey := session.GetRSAPublicKey()
+	rsaPrivKey := session.GetRSAPrivateKey()
+
+	//Load the user ID
+	UID := session.GetCurrentUser().User
+
+	//Load the registration signature
+	regSignature := session.GetRegistrationValidationSignature()
+
+	var wg sync.WaitGroup
+	errChan := make(chan error, len(cl.ndf.Gateways))
+
+	//Get the registered node keys
+	registeredNodes := session.GetNodes()
+
+	salt := session.GetSalt()
+
+	// This variable keeps track of whether there were new registrations
+	// required, thus requiring the state file to be saved again
+	newRegistrations := false
+
+	for i := range cl.ndf.Gateways {
+		localI := i
+		nodeID := *id.NewNodeFromBytes(cl.ndf.Nodes[i].ID)
+		//Register with node if the node has not been registered with already
+		if _, ok := registeredNodes[nodeID]; !ok {
+			wg.Add(1)
+			newRegistrations = true
+			go func() {
+				cl.registerWithNode(localI, salt, regSignature, UID, rsaPubKey, rsaPrivKey,
+					cmixDHPubKey, cmixDHPrivKey, cmixGrp, errChan)
+				wg.Done()
+			}()
+		}
+	}
+
+	wg.Wait()
+	//See if the registration returned errors at all
+	var errs error
+	for len(errChan) > 0 {
+		err := <-errChan
+		if errs != nil {
+			errs = errors.Wrap(errs, err.Error())
+		} else {
+			errs = err
+		}
+
+	}
+	//If an error every occurred, return with error
+	if errs != nil {
+		cl.opStatus(globals.REG_FAIL)
+		return errs
+	}
+
+	// Store the user session if there were changes during node registration
+	if newRegistrations {
+		errStore := session.StoreSession()
+		if errStore != nil {
+			err := errors.Errorf(
+				"Register: could not register due to failed session save"+
+					": %s", errStore.Error())
+			return err
+		}
+	}
+
+	return nil
+}
+
+//registerWithNode registers a user. It serves as a helper for Register
+func (cl *Client) registerWithNode(index int, salt, registrationValidationSignature []byte, UID *id.User,
+	publicKeyRSA *rsa.PublicKey, privateKeyRSA *rsa.PrivateKey,
+	cmixPublicKeyDH, cmixPrivateKeyDH *cyclic.Int,
+	cmixGrp *cyclic.Group, errorChan chan error) {
+
+	gatewayID := id.NewNodeFromBytes(cl.ndf.Nodes[index].ID).NewGateway()
+
+	// Initialise blake2b hash for transmission keys and sha256 for reception
+	// keys
+	transmissionHash, _ := hash.NewCMixHash()
+	receptionHash := sha256.New()
+
+	// Request nonce message from gateway
+	globals.Log.INFO.Printf("Register: Requesting nonce from gateway %v/%v",
+		index+1, len(cl.ndf.Gateways))
+	nonce, dhPub, err := cl.requestNonce(salt, registrationValidationSignature, cmixPublicKeyDH,
+		publicKeyRSA, privateKeyRSA, gatewayID)
+
+	if err != nil {
+		errMsg := errors.Errorf("Register: Failed requesting nonce from gateway: %+v", err)
+		errorChan <- errMsg
+	}
+
+	// Load server DH pubkey
+	serverPubDH := cmixGrp.NewIntFromBytes(dhPub)
+
+	// Confirm received nonce
+	globals.Log.INFO.Println("Register: Confirming received nonce")
+	err = cl.confirmNonce(UID.Bytes(), nonce, privateKeyRSA, gatewayID)
+	if err != nil {
+		errMsg := errors.Errorf("Register: Unable to confirm nonce: %v", err)
+		errorChan <- errMsg
+	}
+	nodeID := cl.topology.GetNodeAtIndex(index)
+	key := user.NodeKeys{
+		TransmissionKey: registration.GenerateBaseKey(cmixGrp,
+			serverPubDH, cmixPrivateKeyDH, transmissionHash),
+		ReceptionKey: registration.GenerateBaseKey(cmixGrp, serverPubDH,
+			cmixPrivateKeyDH, receptionHash),
+	}
+	cl.session.PushNodeKey(nodeID, key)
+}
+
 // UDB Search API
 // Pass a callback function to extract results
 func (cl *Client) SearchForUser(emailAddress string,
diff --git a/api/register.go b/api/register.go
deleted file mode 100644
index 122b62d5729796a7814d6c24e4b89a4f215fc049..0000000000000000000000000000000000000000
--- a/api/register.go
+++ /dev/null
@@ -1,351 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2019 Privategrity Corporation                                   /
-//                                                                             /
-// All rights reserved.                                                        /
-////////////////////////////////////////////////////////////////////////////////
-package api
-
-import (
-	"crypto/rand"
-	"crypto/sha256"
-	"encoding/base64"
-	"github.com/pkg/errors"
-	"gitlab.com/elixxir/client/bots"
-	"gitlab.com/elixxir/client/globals"
-	"gitlab.com/elixxir/client/io"
-	"gitlab.com/elixxir/client/user"
-	"gitlab.com/elixxir/crypto/csprng"
-	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/elixxir/crypto/hash"
-	"gitlab.com/elixxir/crypto/large"
-	"gitlab.com/elixxir/crypto/registration"
-	"gitlab.com/elixxir/crypto/signature/rsa"
-	"gitlab.com/elixxir/primitives/id"
-	"sync"
-	"time"
-)
-
-const SaltSize = 256
-
-// RegisterWithPermissioning registers user with permissioning and returns the
-// User ID.  Returns an error if registration fails.
-func (cl *Client) RegisterWithPermissioning(preCan bool, registrationCode, nick, email,
-	password string, privateKeyRSA *rsa.PrivateKey) (*id.User, error) {
-
-	if !preCan && cl.commManager.GetConnectionStatus() != io.Online {
-		return nil, errors.New("Cannot register when disconnected from the network")
-	}
-
-	var err error
-	var u *user.User
-	var UID *id.User
-
-	cl.opStatus(globals.REG_KEYGEN)
-
-	largeIntBits := 16
-
-	cmixGrp := cyclic.NewGroup(
-		large.NewIntFromString(cl.ndf.CMIX.Prime, largeIntBits),
-		large.NewIntFromString(cl.ndf.CMIX.Generator, largeIntBits))
-
-	e2eGrp := cyclic.NewGroup(
-		large.NewIntFromString(cl.ndf.E2E.Prime, largeIntBits),
-		large.NewIntFromString(cl.ndf.E2E.Generator, largeIntBits))
-
-	// Make CMIX keys array
-	nk := make(map[id.Node]user.NodeKeys)
-
-	// GENERATE CLIENT RSA KEYS
-	if privateKeyRSA == nil {
-		privateKeyRSA, err = rsa.GenerateKey(rand.Reader, rsa.DefaultRSABitLen)
-		if err != nil {
-			return nil, err
-		}
-	}
-
-	publicKeyRSA := privateKeyRSA.GetPublic()
-
-	cmixPrivKeyDHByte, err := csprng.GenerateInGroup(cmixGrp.GetPBytes(), 256, csprng.NewSystemRNG())
-
-	if err != nil {
-		return nil, errors.Errorf("Could not generate cmix DH private key: %s", err.Error())
-	}
-
-	cmixPrivateKeyDH := cmixGrp.NewIntFromBytes(cmixPrivKeyDHByte)
-	cmixPublicKeyDH := cmixGrp.ExpG(cmixPrivateKeyDH, cmixGrp.NewMaxInt())
-
-	e2ePrivKeyDHByte, err := csprng.GenerateInGroup(cmixGrp.GetPBytes(), 256, csprng.NewSystemRNG())
-
-	if err != nil {
-		return nil, errors.Errorf("Could not generate e2e DH private key: %s", err.Error())
-	}
-
-	e2ePrivateKeyDH := e2eGrp.NewIntFromBytes(e2ePrivKeyDHByte)
-	e2ePublicKeyDH := e2eGrp.ExpG(e2ePrivateKeyDH, e2eGrp.NewMaxInt())
-
-	// Initialized response from Registration Server
-	regValidationSignature := make([]byte, 0)
-
-	var salt []byte
-
-	// Handle precanned registration
-	if preCan {
-		cl.opStatus(globals.REG_PRECAN)
-		globals.Log.INFO.Printf("Registering precanned user...")
-		u, UID, nk, err = cl.precannedRegister(registrationCode, nick, nk)
-		if err != nil {
-			errMsg := errors.Errorf("Unable to complete precanned registration: %+v", err)
-			return id.ZeroID, errMsg
-		}
-	} else {
-		cl.opStatus(globals.REG_UID_GEN)
-		globals.Log.INFO.Printf("Registering dynamic user...")
-
-		// Generate salt for UserID
-		salt = make([]byte, SaltSize)
-		_, err = csprng.NewSystemRNG().Read(salt)
-		if err != nil {
-			errMsg := errors.Errorf("Register: Unable to generate salt! %s", err)
-			return id.ZeroID, errMsg
-		}
-
-		// Generate UserID by hashing salt and public key
-		UID = registration.GenUserID(publicKeyRSA, salt)
-
-		// If Registration Server is specified, contact it
-		// Only if registrationCode is set
-		globals.Log.INFO.Println("Register: Contacting registration server")
-		if cl.ndf.Registration.Address != "" && registrationCode != "" {
-			cl.opStatus(globals.REG_PERM)
-			regValidationSignature, err = cl.sendRegistrationMessage(registrationCode, publicKeyRSA)
-			if err != nil {
-				err = errors.Errorf("Register: Unable to send registration message: %+v", err)
-				return id.ZeroID, err
-			}
-		}
-		globals.Log.INFO.Println("Register: successfully passed Registration message")
-
-		var actualNick string
-		if nick != "" {
-			actualNick = nick
-		} else {
-			actualNick = base64.StdEncoding.EncodeToString(UID[:])
-		}
-		u = user.Users.NewUser(UID, actualNick)
-		user.Users.UpsertUser(u)
-	}
-
-	cl.opStatus(globals.REG_SECURE_STORE)
-
-	u.Email = email
-
-	// Create the user session
-	newSession := user.NewSession(cl.storage, u, nk, publicKeyRSA,
-		privateKeyRSA, cmixPublicKeyDH, cmixPrivateKeyDH, e2ePublicKeyDH,
-		e2ePrivateKeyDH, salt, cmixGrp, e2eGrp, password, regValidationSignature)
-	cl.opStatus(globals.REG_SAVE)
-
-	//set the registration state
-	err = newSession.SetRegState(user.PermissioningComplete)
-	if err != nil {
-		return id.ZeroID, errors.Wrap(err, "Permissioning Registration "+
-			"Failed")
-	}
-
-	// Store the user session
-	errStore := newSession.StoreSession()
-
-	if errStore != nil {
-		errMsg := errors.Errorf(
-			"Permissioning Register: could not register due to failed session save"+
-				": %s", errStore.Error())
-		return id.ZeroID, errMsg
-	}
-	cl.session = newSession
-	return UID, nil
-}
-
-// RegisterWithUDB uses the account's email to register with the UDB for
-// User discovery.  Must be called after Register and Connect.
-// It will fail if the user has already registered with UDB
-func (cl *Client) RegisterWithUDB(timeout time.Duration) error {
-
-	regState := cl.GetSession().GetRegState()
-
-	if regState != user.PermissioningComplete {
-		return errors.New("Cannot register with UDB when registration " +
-			"state is not PermissioningComplete")
-	}
-
-	status := cl.commManager.GetConnectionStatus()
-	if status == io.Connecting || status == io.Offline {
-		return errors.New("ERROR: could not RegisterWithUDB - connection is either offline or connecting")
-	}
-
-	email := cl.session.GetCurrentUser().Email
-
-	var err error
-
-	if email != "" {
-		globals.Log.INFO.Printf("Registering user as %s with UDB", email)
-
-		valueType := "EMAIL"
-
-		publicKeyBytes := cl.session.GetE2EDHPublicKey().Bytes()
-		err = bots.Register(valueType, email, publicKeyBytes, cl.opStatus, timeout)
-		if err == nil {
-			globals.Log.INFO.Printf("Registered with UDB!")
-		} else {
-			globals.Log.WARN.Printf("Could not register with UDB: %s", err)
-		}
-
-	} else {
-		globals.Log.INFO.Printf("Not registering with UDB because no " +
-			"email found")
-	}
-
-	if err != nil {
-		return errors.Wrap(err, "Could not register with UDB")
-	}
-
-	//set the registration state
-	err = cl.session.SetRegState(user.UDBComplete)
-
-	if err != nil {
-		return errors.Wrap(err, "UDB Registration Failed")
-	}
-
-	errStore := cl.session.StoreSession()
-
-	// FIXME If we have an error here, the session that gets created
-	// doesn't get immolated. Immolation should happen in a deferred
-	//  call instead.
-	if errStore != nil {
-		errMsg := errors.Errorf(
-			"UDB Register: could not register due to failed session save"+
-				": %s", errStore.Error())
-		return errMsg
-	}
-
-	return nil
-}
-
-func (cl *Client) RegisterWithNodes() error {
-	session := cl.GetSession()
-	//Load Cmix keys & group
-	cmixDHPrivKey := session.GetCMIXDHPrivateKey()
-	cmixDHPubKey := session.GetCMIXDHPublicKey()
-	cmixGrp := session.GetCmixGroup()
-
-	//Load the rsa keys
-	rsaPubKey := session.GetRSAPublicKey()
-	rsaPrivKey := session.GetRSAPrivateKey()
-
-	//Load the user ID
-	UID := session.GetCurrentUser().User
-
-	//Load the registration signature
-	regSignature := session.GetRegistrationValidationSignature()
-
-	var wg sync.WaitGroup
-	errChan := make(chan error, len(cl.ndf.Gateways))
-
-	//Get the registered node keys
-	registeredNodes := session.GetNodes()
-
-	salt := session.GetSalt()
-
-	// This variable keeps track of whether there were new registrations
-	// required, thus requiring the state file to be saved again
-	newRegistrations := false
-
-	for i := range cl.ndf.Gateways {
-		localI := i
-		nodeID := *id.NewNodeFromBytes(cl.ndf.Nodes[i].ID)
-		//Register with node if the node has not been registered with already
-		if _, ok := registeredNodes[nodeID]; !ok {
-			wg.Add(1)
-			newRegistrations = true
-			go func() {
-				cl.registerWithNode(localI, salt, regSignature, UID, rsaPubKey, rsaPrivKey,
-					cmixDHPubKey, cmixDHPrivKey, cmixGrp, errChan)
-				wg.Done()
-			}()
-		}
-	}
-
-	wg.Wait()
-	//See if the registration returned errors at all
-	var errs error
-	for len(errChan) > 0 {
-		err := <-errChan
-		if errs != nil {
-			errs = errors.Wrap(errs, err.Error())
-		} else {
-			errs = err
-		}
-
-	}
-	//If an error every occurred, return with error
-	if errs != nil {
-		cl.opStatus(globals.REG_FAIL)
-		return errs
-	}
-
-	// Store the user session if there were changes during node registration
-	if newRegistrations {
-		errStore := session.StoreSession()
-		if errStore != nil {
-			err := errors.Errorf(
-				"Register: could not register due to failed session save"+
-					": %s", errStore.Error())
-			return err
-		}
-	}
-
-	return nil
-}
-
-//registerWithNode registers a user. It serves as a helper for Register
-func (cl *Client) registerWithNode(index int, salt, registrationValidationSignature []byte, UID *id.User,
-	publicKeyRSA *rsa.PublicKey, privateKeyRSA *rsa.PrivateKey,
-	cmixPublicKeyDH, cmixPrivateKeyDH *cyclic.Int,
-	cmixGrp *cyclic.Group, errorChan chan error) {
-
-	gatewayID := id.NewNodeFromBytes(cl.ndf.Nodes[index].ID).NewGateway()
-
-	// Initialise blake2b hash for transmission keys and sha256 for reception
-	// keys
-	transmissionHash, _ := hash.NewCMixHash()
-	receptionHash := sha256.New()
-
-	// Request nonce message from gateway
-	globals.Log.INFO.Printf("Register: Requesting nonce from gateway %v/%v",
-		index+1, len(cl.ndf.Gateways))
-	nonce, dhPub, err := cl.requestNonce(salt, registrationValidationSignature, cmixPublicKeyDH,
-		publicKeyRSA, privateKeyRSA, gatewayID)
-
-	if err != nil {
-		errMsg := errors.Errorf("Register: Failed requesting nonce from gateway: %+v", err)
-		errorChan <- errMsg
-	}
-
-	// Load server DH pubkey
-	serverPubDH := cmixGrp.NewIntFromBytes(dhPub)
-
-	// Confirm received nonce
-	globals.Log.INFO.Println("Register: Confirming received nonce")
-	err = cl.confirmNonce(UID.Bytes(), nonce, privateKeyRSA, gatewayID)
-	if err != nil {
-		errMsg := errors.Errorf("Register: Unable to confirm nonce: %v", err)
-		errorChan <- errMsg
-	}
-	nodeID := cl.topology.GetNodeAtIndex(index)
-	key := user.NodeKeys{
-		TransmissionKey: registration.GenerateBaseKey(cmixGrp,
-			serverPubDH, cmixPrivateKeyDH, transmissionHash),
-		ReceptionKey: registration.GenerateBaseKey(cmixGrp, serverPubDH,
-			cmixPrivateKeyDH, receptionHash),
-	}
-	cl.session.PushNodeKey(nodeID, key)
-}