diff --git a/Makefile b/Makefile
index 7cd635a516d953f796d6073610b0f4d6693e00db..57d0d9c1653fba410e97ee25fafd63fe5006ae0a 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,7 @@ clean:
 	go mod vendor
 
 update:
-	-GOFLAGS="" go get -u all
+	-GOFLAGS="" go get all
 
 build:
 	go build ./...
diff --git a/README.md b/README.md
index 0cd7989af96e9851126932c253e8385c3f9ea8d7..3827baea0e49a5792e8bd230f6e90230bcccca9d 100644
--- a/README.md
+++ b/README.md
@@ -176,6 +176,9 @@ Flags:
                                   (default 500)
       --sendid uint               Use precanned user id (must be between 1 and
                                   40, inclusive)
+      --slowPolling bool          Enables polling for all network updates and RSA signed rounds.
+                                  Defaults to true (filtered updates with ECC signed rounds) if not set
+
   -s, --session string            Sets the initial directory for client storage
       --unsafe                    Send raw, unsafe messages without e2e
                                   encryption.
diff --git a/api/notifications.go b/api/notifications.go
index da7f6642a4678b7e25efe217ef34d9c8542d1057..2a7d1b7c107128360f89930c8bf0bcb16dfc54de 100644
--- a/api/notifications.go
+++ b/api/notifications.go
@@ -34,7 +34,6 @@ func (c *Client) RegisterForNotifications(token string) error {
 	if err != nil {
 		return err
 	}
-	jww.INFO.Printf("Sending RegisterForNotifications message")
 	// Send the register message
 	_, err = c.comms.RegisterForNotifications(notificationBotHost,
 		&mixmessages.NotificationRegisterRequest{
@@ -44,6 +43,7 @@ func (c *Client) RegisterForNotifications(token string) error {
 			TransmissionSalt:      c.GetUser().TransmissionSalt,
 			TransmissionRsaSig:    c.GetStorage().User().GetTransmissionRegistrationValidationSignature(),
 			IIDTransmissionRsaSig: sig,
+			RegistrationTimestamp: c.GetUser().RegistrationTimestamp.UnixNano(),
 		})
 	if err != nil {
 		err := errors.Errorf(
diff --git a/api/permissioning.go b/api/permissioning.go
index b4691291befcb12e7b28b06948980ecc76143c78..cf0d3cb89a9de3dc37bcee689c2a23dc8f06d855 100644
--- a/api/permissioning.go
+++ b/api/permissioning.go
@@ -27,7 +27,8 @@ func (c *Client) registerWithPermissioning() error {
 	}
 
 	//register with permissioning
-	transmissionRegValidationSignature, receptionRegValidationSignature, err := c.permissioning.Register(transmissionPubKey, receptionPubKey, regCode)
+	transmissionRegValidationSignature, receptionRegValidationSignature,
+		registrationTimestamp, err := c.permissioning.Register(transmissionPubKey, receptionPubKey, regCode)
 	if err != nil {
 		return errors.WithMessage(err, "failed to register with "+
 			"permissioning")
@@ -36,6 +37,7 @@ func (c *Client) registerWithPermissioning() error {
 	//store the signature
 	userData.SetTransmissionRegistrationValidationSignature(transmissionRegValidationSignature)
 	userData.SetReceptionRegistrationValidationSignature(receptionRegValidationSignature)
+	userData.SetRegistrationTimestamp(registrationTimestamp)
 
 	//update the registration status
 	err = c.storage.ForwardRegistrationStatus(storage.PermissioningComplete)
diff --git a/api/results_test.go b/api/results_test.go
index 54433f2e9b8bcfd91e3d83e5745bdc1d3ceecc75..68e21e9aca1a317bada3ea1497c90166b1b4289c 100644
--- a/api/results_test.go
+++ b/api/results_test.go
@@ -40,7 +40,7 @@ func TestClient_GetRoundResults(t *testing.T) {
 	// Create a new copy of the test client for this test
 	client, err := newTestingClient(t)
 	if err != nil {
-		t.Errorf("Failed in setup: %v", err)
+		t.Fatalf("Failed in setup: %v", err)
 	}
 
 	// Construct the round call back function signature
@@ -103,7 +103,7 @@ func TestClient_GetRoundResults_FailedRounds(t *testing.T) {
 	// Create a new copy of the test client for this test
 	client, err := newTestingClient(t)
 	if err != nil {
-		t.Errorf("Failed in setup: %v", err)
+		t.Fatalf("Failed in setup: %v", err)
 	}
 
 	// Construct the round call back function signature
@@ -161,7 +161,7 @@ func TestClient_GetRoundResults_HistoricalRounds(t *testing.T) {
 	// Create a new copy of the test client for this test
 	client, err := newTestingClient(t)
 	if err != nil {
-		t.Errorf("Failed in setup: %v", err)
+		t.Fatalf("Failed in setup: %v", err)
 	}
 
 	// Overpopulate the round buffer, ensuring a circle back of the ring buffer
@@ -219,7 +219,7 @@ func TestClient_GetRoundResults_Timeout(t *testing.T) {
 	// Create a new copy of the test client for this test
 	client, err := newTestingClient(t)
 	if err != nil {
-		t.Errorf("Failed in setup: %v", err)
+		t.Fatalf("Failed in setup: %v", err)
 	}
 
 	// Construct the round call back function signature
diff --git a/api/utils_test.go b/api/utils_test.go
index 9b9fccac0225438387907c405efbcc023fa0e5a6..a20f1e0bf64a0da34935d467ac483caccd742dce 100644
--- a/api/utils_test.go
+++ b/api/utils_test.go
@@ -62,7 +62,7 @@ func newTestingClient(face interface{}) (*Client, error) {
 
 	thisInstance, err := network.NewInstanceTesting(instanceComms, def, def, nil, nil, face)
 	if err != nil {
-		return nil, nil
+		return nil, err
 	}
 
 	p := gateway.DefaultPoolParams()
@@ -87,6 +87,7 @@ func getNDF(face interface{}) *ndf.NetworkDefinition {
 	return &ndf.NetworkDefinition{
 		Registration: ndf.Registration{
 			TlsCertificate: string(cert),
+			EllipticPubKey: "/WRtT+mDZGC3FXQbvuQgfqOonAjJ47IKE0zhaGTQQ70=",
 		},
 		Nodes: []ndf.Node{
 			{
@@ -151,6 +152,6 @@ func signRoundInfo(ri *pb.RoundInfo) error {
 
 	ourPrivateKey := &rsa.PrivateKey{PrivateKey: *pk}
 
-	return signature.Sign(ri, ourPrivateKey)
+	return signature.SignRsa(ri, ourPrivateKey)
 
 }
diff --git a/api/version_vars.go b/api/version_vars.go
index 7ca866b7d96c690d27065573c80a38bd52916839..25387358190275af6114f57baee417c297d9fb20 100644
--- a/api/version_vars.go
+++ b/api/version_vars.go
@@ -1,9 +1,9 @@
 // Code generated by go generate; DO NOT EDIT.
 // This file was generated by robots at
-// 2021-05-14 10:40:35.967865 -0700 PDT m=+0.035901934
+// 2021-05-20 15:24:04.3341818 -0700 PDT m=+0.193117301
 package api
 
-const GITVERSION = `7db53dd8 update go mod`
+const GITVERSION = `4f3b5a13 update deps`
 const SEMVER = "2.6.0"
 const DEPENDENCIES = `module gitlab.com/elixxir/client
 
@@ -24,18 +24,18 @@ require (
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/viper v1.7.1
 	gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228
-	gitlab.com/elixxir/comms v0.0.4-0.20210506164842-7a132fdd895a
-	gitlab.com/elixxir/crypto v0.0.7-0.20210514172618-7745b6e1c865
+	gitlab.com/elixxir/comms v0.0.4-0.20210519214834-4b27f37412f1
+	gitlab.com/elixxir/crypto v0.0.7-0.20210519214631-6e1aedaf8d0c
 	gitlab.com/elixxir/ekv v0.1.5
-	gitlab.com/elixxir/primitives v0.0.3-0.20210514171434-8ec71ecbb058
-	gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365
-	gitlab.com/xx_network/crypto v0.0.5-0.20210504210244-9ddabbad25fd
-	gitlab.com/xx_network/primitives v0.0.4-0.20210504205835-db68f11de78a
+	gitlab.com/elixxir/primitives v0.0.3-0.20210520220650-16cb34e6b7e3
+	gitlab.com/xx_network/comms v0.0.4-0.20210517205649-06ddfa8d2a75
+	gitlab.com/xx_network/crypto v0.0.5-0.20210517205543-4ae99cbb9063
+	gitlab.com/xx_network/primitives v0.0.4-0.20210517202253-c7b4bd0087ea
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
-	golang.org/x/net v0.0.0-20210505214959-0714010a04ed
-	golang.org/x/sys v0.0.0-20210503173754-0981d6026fa6 // indirect
-	google.golang.org/genproto v0.0.0-20201030142918-24207fddd1c3 // indirect
-	google.golang.org/grpc v1.37.0 // indirect
+	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
+	golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
+	google.golang.org/genproto v0.0.0-20210105202744-fe13368bc0e1 // indirect
+	google.golang.org/grpc v1.34.0 // indirect
 	google.golang.org/protobuf v1.26.0-rc.1
 	gopkg.in/ini.v1 v1.62.0 // indirect
 )
diff --git a/cmd/root.go b/cmd/root.go
index 7d017680700bfce74ed8c4f0613f3672e1ecf81d..f4a03506ab5766a277c26cf351751f9a5dc347c1 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -347,6 +347,7 @@ func createClient() *api.Client {
 	netParams.E2EParams.NumRekeys = uint16(
 		viper.GetUint("e2eNumReKeys"))
 	netParams.ForceHistoricalRounds = viper.GetBool("forceHistoricalRounds")
+	netParams.FastPolling = !viper.GetBool("slowPolling")
 
 	client, err := api.OpenClient(storeDir, []byte(pass), netParams)
 	if err != nil {
@@ -367,6 +368,7 @@ func initClient() *api.Client {
 	netParams.E2EParams.NumRekeys = uint16(
 		viper.GetUint("e2eNumReKeys"))
 	netParams.ForceHistoricalRounds = viper.GetBool("forceHistoricalRounds")
+	netParams.FastPolling = viper.GetBool(" slowPolling")
 
 	//load the client
 	client, err := api.Login(storeDir, []byte(pass), netParams)
@@ -762,6 +764,12 @@ func init() {
 	viper.BindPFlag("forceHistoricalRounds",
 		rootCmd.Flags().Lookup("forceHistoricalRounds"))
 
+	// Network params
+	rootCmd.Flags().BoolP("slowPolling", "", false,
+		"Enables polling for unfiltered network updates with RSA signatures")
+	viper.BindPFlag("slowPolling",
+		rootCmd.Flags().Lookup("slowPolling"))
+
 	// E2E Params
 	defaultE2EParams := params.GetDefaultE2ESessionParams()
 	rootCmd.Flags().UintP("e2eMinKeys",
diff --git a/go.mod b/go.mod
index 0625e9acabb938a6c7c1fa10d8e08b646f64f249..7a624d8d898fb18f26f27efd965043689e775e82 100644
--- a/go.mod
+++ b/go.mod
@@ -17,13 +17,13 @@ require (
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/spf13/viper v1.7.1
 	gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228
-	gitlab.com/elixxir/comms v0.0.4-0.20210514193223-7efa4c966f23
-	gitlab.com/elixxir/crypto v0.0.7-0.20210514185043-7398614e9e43
+	gitlab.com/elixxir/comms v0.0.4-0.20210520231539-ca1bbeb6e3ec
+	gitlab.com/elixxir/crypto v0.0.7-0.20210520231341-cc91d0be28ae
 	gitlab.com/elixxir/ekv v0.1.5
-	gitlab.com/elixxir/primitives v0.0.3-0.20210514174939-fbba435364ed
-	gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365
-	gitlab.com/xx_network/crypto v0.0.5-0.20210504210244-9ddabbad25fd
-	gitlab.com/xx_network/primitives v0.0.4-0.20210504205835-db68f11de78a
+	gitlab.com/elixxir/primitives v0.0.3-0.20210520220650-16cb34e6b7e3
+	gitlab.com/xx_network/comms v0.0.4-0.20210517205649-06ddfa8d2a75
+	gitlab.com/xx_network/crypto v0.0.5-0.20210517205543-4ae99cbb9063
+	gitlab.com/xx_network/primitives v0.0.4-0.20210517202253-c7b4bd0087ea
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
 	golang.org/x/net v0.0.0-20210226172049-e18ecbb05110
 	golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57 // indirect
diff --git a/go.sum b/go.sum
index 608786e20c6cce9b86db3173cd38459cdddb25a8..c2dfb2c3875688101ee7be90c56f1cba175c27ac 100644
--- a/go.sum
+++ b/go.sum
@@ -253,14 +253,18 @@ github.com/zeebo/pcg v1.0.0 h1:dt+dx+HvX8g7Un32rY9XWoYnd0NmKmrIzpHF7qiTDj0=
 github.com/zeebo/pcg v1.0.0/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l4=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228 h1:Gi6rj4mAlK0BJIk1HIzBVMjWNjIUfstrsXC2VqLYPcA=
 gitlab.com/elixxir/bloomfilter v0.0.0-20200930191214-10e9ac31b228/go.mod h1:H6jztdm0k+wEV2QGK/KYA+MY9nj9Zzatux/qIvDDv3k=
-gitlab.com/elixxir/comms v0.0.4-0.20210514193223-7efa4c966f23 h1:rXx1Pc6H72jZh94AH4CwFifZ5eCOZ/SfNIk7yP0vNZA=
-gitlab.com/elixxir/comms v0.0.4-0.20210514193223-7efa4c966f23/go.mod h1:pwfLDUtrurM8mDcU11QHtBgxhL6cb5Vf/R47zJ7enuQ=
+gitlab.com/elixxir/comms v0.0.4-0.20210519214834-4b27f37412f1 h1:GauO2zR/wVc0zTTtJ8iX2Hzs3LFeLlQAiGfAZWDYssE=
+gitlab.com/elixxir/comms v0.0.4-0.20210519214834-4b27f37412f1/go.mod h1:hdLuXAbKt9YzI637EZdoWpPC9C6hEsBXa21IsCBbZc8=
+gitlab.com/elixxir/comms v0.0.4-0.20210520231539-ca1bbeb6e3ec h1:a9Ic9N0qZpuG4N9kIU+m9QcTXF7qh73+y46n/StCHBE=
+gitlab.com/elixxir/comms v0.0.4-0.20210520231539-ca1bbeb6e3ec/go.mod h1:OE24JSQ7bMGCHvw75HIBr6o11onU8k43HYDbalm8muE=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4 h1:28ftZDeYEko7xptCZzeFWS1Iam95dj46TWFVVlKmw6A=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
 gitlab.com/elixxir/crypto v0.0.3 h1:znCt/x2bL4y8czTPaaFkwzdgSgW3BJc/1+dxyf1jqVw=
 gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
-gitlab.com/elixxir/crypto v0.0.7-0.20210514185043-7398614e9e43 h1:YrHC861+C0DZPXXEV567TUUleFt35EMe55pvPztjnV8=
-gitlab.com/elixxir/crypto v0.0.7-0.20210514185043-7398614e9e43/go.mod h1:iL2uGUFjLT3Z97IjsCSSqmfRlSJ6Y/uIWEPZLEOKyys=
+gitlab.com/elixxir/crypto v0.0.7-0.20210519214631-6e1aedaf8d0c h1:N/ErhUa4VfsAs3obrJfbrplnZm6jqCvdY55gMAGdQPo=
+gitlab.com/elixxir/crypto v0.0.7-0.20210519214631-6e1aedaf8d0c/go.mod h1:Mjs4etcq67zC1Wa60RahhgAIavbtiK6zAuJVwsjGhrk=
+gitlab.com/elixxir/crypto v0.0.7-0.20210520231341-cc91d0be28ae h1:EKA7z0CclY30bEnt+6ZOcyZrEwWoYVz9vn+cgpx9/Rk=
+gitlab.com/elixxir/crypto v0.0.7-0.20210520231341-cc91d0be28ae/go.mod h1:dWTNCyFkDlUiJh/rHRV2PHnu/akReOoXSTjpEOs9Py0=
 gitlab.com/elixxir/ekv v0.1.5 h1:R8M1PA5zRU1HVnTyrtwybdABh7gUJSCvt1JZwUSeTzk=
 gitlab.com/elixxir/ekv v0.1.5/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4=
 gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
@@ -268,23 +272,25 @@ gitlab.com/elixxir/primitives v0.0.0-20200804170709-a1896d262cd9/go.mod h1:p0Vel
 gitlab.com/elixxir/primitives v0.0.0-20200804182913-788f47bded40/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc=
 gitlab.com/elixxir/primitives v0.0.1 h1:q61anawANlNAExfkeQEE1NCsNih6vNV1FFLoUQX6txQ=
 gitlab.com/elixxir/primitives v0.0.1/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2YKnw5c+LJCE=
-gitlab.com/elixxir/primitives v0.0.3-0.20210514174939-fbba435364ed h1:iRNiL2PkHDgcPQt5qUlOtod0n0sSyaSNXN+AkmZ5ViA=
-gitlab.com/elixxir/primitives v0.0.3-0.20210514174939-fbba435364ed/go.mod h1:4pNgiFEQQ11hHCXBRQJN1w9AIuKa1HTlPTxs9UYOXFA=
+gitlab.com/elixxir/primitives v0.0.3-0.20210519212350-6ad72cbae82c h1:jDLyFcsYAyHQEkwN7Mws1gX0PyBGwXoI7jdtU7Fz6DY=
+gitlab.com/elixxir/primitives v0.0.3-0.20210519212350-6ad72cbae82c/go.mod h1:TR4FpK1b+IE4IlDmvMnCAM0qqtrF1aYNUd+bnhRiAKI=
+gitlab.com/elixxir/primitives v0.0.3-0.20210520220650-16cb34e6b7e3 h1:ZhuILY/OhL8wEDulQVtgYJlC48jdWxAzarQW2xQF0JA=
+gitlab.com/elixxir/primitives v0.0.3-0.20210520220650-16cb34e6b7e3/go.mod h1:TR4FpK1b+IE4IlDmvMnCAM0qqtrF1aYNUd+bnhRiAKI=
 gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw=
-gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365 h1:VjeUUy4hcc2uTOO5qZ0roJlGHySWJxN/G7bf1VnLfFM=
-gitlab.com/xx_network/comms v0.0.4-0.20210507215532-38ed97bd9365/go.mod h1:RkNZ0CjeXKRhEFdUeAdCAF6QuK8sO1j2bUg9oqK0OEA=
+gitlab.com/xx_network/comms v0.0.4-0.20210517205649-06ddfa8d2a75 h1:l5szLkEfBQMa2eEt1mQf0B+Dp2pckT2y37at1MWfNj4=
+gitlab.com/xx_network/comms v0.0.4-0.20210517205649-06ddfa8d2a75/go.mod h1:qxX3x7yCATvaK8hhFibl2Rnnb+xvLior/AJlx2dk1UM=
 gitlab.com/xx_network/crypto v0.0.3/go.mod h1:DF2HYvvCw9wkBybXcXAgQMzX+MiGbFPjwt3t17VRqRE=
 gitlab.com/xx_network/crypto v0.0.4 h1:lpKOL5mTJ2awWMfgBy30oD/UvJVrWZzUimSHlOdZZxo=
 gitlab.com/xx_network/crypto v0.0.4/go.mod h1:+lcQEy+Th4eswFgQDwT0EXKp4AXrlubxalwQFH5O0Mk=
-gitlab.com/xx_network/crypto v0.0.5-0.20210504210244-9ddabbad25fd h1:jSY1ogxa2/MXthD8jadGr7IYBL4vXQID3VZp1g0GWec=
-gitlab.com/xx_network/crypto v0.0.5-0.20210504210244-9ddabbad25fd/go.mod h1:bAqc5+q2K9OXWceHkZX+VnneSKlsSeg+G98O5S4Y2cA=
+gitlab.com/xx_network/crypto v0.0.5-0.20210517205543-4ae99cbb9063 h1:BW6kQCHP5dySBWuaKjfU6gP+Wbw5Dnr8GTRzaEbF1zU=
+gitlab.com/xx_network/crypto v0.0.5-0.20210517205543-4ae99cbb9063/go.mod h1:AOUw4RJfBrKDXbe9nY/8bM3ID1czcooefUbVd82zrCY=
 gitlab.com/xx_network/primitives v0.0.0-20200803231956-9b192c57ea7c/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA=
 gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da h1:CCVslUwNC7Ul7NG5nu3ThGTSVUt1TxNRX+47f5TUwnk=
 gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug=
 gitlab.com/xx_network/primitives v0.0.2 h1:r45yKenJ9e7PylI1ZXJ1Es09oYNaYXjxVy9+uYlwo7Y=
 gitlab.com/xx_network/primitives v0.0.2/go.mod h1:cs0QlFpdMDI6lAo61lDRH2JZz+3aVkHy+QogOB6F/qc=
-gitlab.com/xx_network/primitives v0.0.4-0.20210504205835-db68f11de78a h1:Op+Dfm/Swtrs6Lgo/ro28SrCrftrfQtK9a3/EOoXYAo=
-gitlab.com/xx_network/primitives v0.0.4-0.20210504205835-db68f11de78a/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE=
+gitlab.com/xx_network/primitives v0.0.4-0.20210517202253-c7b4bd0087ea h1:yiFyOC+qhTLO/AjCOuL7hNNkD4VdPnnSmeYXXQwmGYE=
+gitlab.com/xx_network/primitives v0.0.4-0.20210517202253-c7b4bd0087ea/go.mod h1:9imZHvYwNFobxueSvVtHneZLk9wTK7HQTzxPm+zhFhE=
 gitlab.com/xx_network/ring v0.0.2 h1:TlPjlbFdhtJrwvRgIg4ScdngMTaynx/ByHBRZiXCoL0=
 gitlab.com/xx_network/ring v0.0.2/go.mod h1:aLzpP2TiZTQut/PVHR40EJAomzugDdHXetbieRClXIM=
 go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
diff --git a/interfaces/params/network.go b/interfaces/params/network.go
index 24af3d540f2e7824328641c07ddf325c37e86dfc..2f11441ea0b6ceb50924dbb163421051912d1bab 100644
--- a/interfaces/params/network.go
+++ b/interfaces/params/network.go
@@ -25,6 +25,10 @@ type Network struct {
 	ParallelNodeRegistrations uint
 	//How far back in rounds the network should actually check
 	KnownRoundsThreshold uint
+	// Determines verbosity of network updates while polling
+	// If true, client receives a filtered set of updates
+	// If false, client receives the full list of network updates
+	FastPolling bool
 
 	Rounds
 	Messages
@@ -42,6 +46,7 @@ func GetDefaultNetwork() Network {
 		E2EParams:                 GetDefaultE2ESessionParams(),
 		ParallelNodeRegistrations: 8,
 		KnownRoundsThreshold:      1500, //5 rounds/sec * 60 sec/min * 5 min
+		FastPolling:               true,
 	}
 	n.Rounds = GetDefaultRounds()
 	n.Messages = GetDefaultMessage()
diff --git a/interfaces/user/user.go b/interfaces/user/user.go
index 7d480700e0e1c048b4ac9fcd98edb6fb25112b51..8788856b494cf386dbd903510680935f2b320daa 100644
--- a/interfaces/user/user.go
+++ b/interfaces/user/user.go
@@ -13,6 +13,7 @@ import (
 	"gitlab.com/elixxir/primitives/fact"
 	"gitlab.com/xx_network/crypto/signature/rsa"
 	"gitlab.com/xx_network/primitives/id"
+	"time"
 )
 
 type User struct {
@@ -24,6 +25,8 @@ type User struct {
 	ReceptionSalt    []byte
 	ReceptionRSA     *rsa.PrivateKey
 	Precanned        bool
+	// Timestamp in which user has registered with the network
+	RegistrationTimestamp time.Time
 
 	//cmix Identity
 	CmixDhPrivateKey *cyclic.Int
diff --git a/keyExchange/confirm_test.go b/keyExchange/confirm_test.go
index 8cef6f6f60488568614208f751914332ca5267f9..10c5ab525f3bf266f8548a6503bf14ee4c011266 100644
--- a/keyExchange/confirm_test.go
+++ b/keyExchange/confirm_test.go
@@ -20,8 +20,14 @@ import (
 // Smoke test for handleTrigger
 func TestHandleConfirm(t *testing.T) {
 	// Generate alice and bob's session
-	aliceSession, _ := InitTestingContextGeneric(t)
-	bobSession, _ := InitTestingContextGeneric(t)
+	aliceSession, _, err := InitTestingContextGeneric(t)
+	if err != nil {
+		t.Fatalf("Failed to create alice session: %v", err)
+	}
+	bobSession, _, err := InitTestingContextGeneric(t)
+	if err != nil {
+		t.Fatalf("Failed to create bob session: %v", err)
+	}
 
 	// Maintain an ID for bob
 	bobID := id.NewIdFromBytes([]byte("test"), t)
diff --git a/keyExchange/rekey.go b/keyExchange/rekey.go
index f37e2e679715a3750ec40a8f9deed924476c32ad..f2aab4c42ebedebd258e83168461b719821e1ef2 100644
--- a/keyExchange/rekey.go
+++ b/keyExchange/rekey.go
@@ -137,7 +137,7 @@ func negotiate(instance *network.Instance, sendE2E interfaces.SendE2E,
 
 	// otherwise, the transmission is a success and this should be denoted
 	// in the session and the log
-	jww.INFO.Printf("Key Negotiation transmission for %s sucesful",
+	jww.INFO.Printf("Key Negotiation transmission for %s successful",
 		session)
 	session.SetNegotiationStatus(e2e.Sent)
 
diff --git a/keyExchange/trigger.go b/keyExchange/trigger.go
index a72da7b110c92e0065a5f9acaf79698565f8815c..e22dd76f0b30974254de9fb6bd356e8e3f69d88e 100644
--- a/keyExchange/trigger.go
+++ b/keyExchange/trigger.go
@@ -153,7 +153,7 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager,
 	// otherwise, the transmission is a success and this should be denoted
 	// in the session and the log
 	sess.GetCriticalMessages().Succeeded(m)
-	jww.INFO.Printf("Key Negotiation transmission for %s sucesfull",
+	jww.INFO.Printf("Key Negotiation transmission for %s successfully",
 		session)
 
 	return nil
diff --git a/keyExchange/trigger_test.go b/keyExchange/trigger_test.go
index 430bba91a0ba734541b03a61260493caa03237e0..5dce2d6a7c50c8e774c3ecd88dd00f5e3db1cacc 100644
--- a/keyExchange/trigger_test.go
+++ b/keyExchange/trigger_test.go
@@ -23,9 +23,14 @@ import (
 // Smoke test for handleTrigger
 func TestHandleTrigger(t *testing.T) {
 	// Generate alice and bob's session
-	aliceSession, aliceManager := InitTestingContextGeneric(t)
-	bobSession, _ := InitTestingContextGeneric(t)
-
+	aliceSession, aliceManager, err := InitTestingContextGeneric(t)
+	if err != nil {
+		t.Fatalf("Failed to create alice session: %v", err)
+	}
+	bobSession, _, err := InitTestingContextGeneric(t)
+	if err != nil {
+		t.Fatalf("Failed to create bob session: %v", err)
+	}
 	// Pull the keys for Alice and Bob
 	alicePrivKey := aliceSession.E2e().GetDHPrivateKey()
 	bobPubKey := bobSession.E2e().GetDHPublicKey()
@@ -62,7 +67,7 @@ func TestHandleTrigger(t *testing.T) {
 	// Handle the trigger and check for an error
 	rekeyParams := params.GetDefaultRekey()
 	rekeyParams.RoundTimeout = 0 * time.Second
-	err := handleTrigger(aliceSession, aliceManager, receiveMsg, rekeyParams)
+	err = handleTrigger(aliceSession, aliceManager, receiveMsg, rekeyParams)
 	if err != nil {
 		t.Errorf("Handle trigger error: %v", err)
 	}
diff --git a/keyExchange/utils_test.go b/keyExchange/utils_test.go
index a23e673f3a258164e4e2c407defbb5dabd5394d9..58c21e7fef3e722ce5377217e36edc72248ffb31 100644
--- a/keyExchange/utils_test.go
+++ b/keyExchange/utils_test.go
@@ -108,7 +108,7 @@ func (t *testNetworkManagerGeneric) GetSender() *gateway.Sender {
 	return nil
 }
 
-func InitTestingContextGeneric(i interface{}) (*storage.Session, interfaces.NetworkManager) {
+func InitTestingContextGeneric(i interface{}) (*storage.Session, interfaces.NetworkManager, error) {
 	switch i.(type) {
 	case *testing.T, *testing.M, *testing.B, *testing.PB:
 		break
@@ -125,12 +125,12 @@ func InitTestingContextGeneric(i interface{}) (*storage.Session, interfaces.Netw
 
 	thisInstance, err := network.NewInstanceTesting(instanceComms, def, def, nil, nil, i)
 	if err != nil {
-		return nil, nil
+		return nil, nil, err
 	}
 
 	thisManager := &testNetworkManagerGeneric{instance: thisInstance}
 
-	return thisSession, thisManager
+	return thisSession, thisManager, nil
 
 }
 
@@ -304,5 +304,8 @@ func getNDF() *ndf.NetworkDefinition {
 				"BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0" +
 				"DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7",
 		},
+		Registration: ndf.Registration{
+			EllipticPubKey: "/WRtT+mDZGC3FXQbvuQgfqOonAjJ47IKE0zhaGTQQ70=",
+		},
 	}
 }
diff --git a/network/ephemeral/tracker_test.go b/network/ephemeral/tracker_test.go
index aa4589ebe7650ab55d4d04ab97fb98cfb9d1c008..e6c3e11f8fd3b8a9e120f3634cac636b385f66c6 100644
--- a/network/ephemeral/tracker_test.go
+++ b/network/ephemeral/tracker_test.go
@@ -105,7 +105,7 @@ func setupInstance(instance interfaces.NetworkManager) error {
 	if err != nil {
 		return errors.Errorf("Failed to load cert from from file: %v", err)
 	}
-	if err = signature.Sign(ri, testCert); err != nil {
+	if err = signature.SignRsa(ri, testCert); err != nil {
 		return errors.Errorf("Failed to sign round info: %v", err)
 	}
 	if err = instance.GetInstance().RoundUpdate(ri); err != nil {
@@ -115,7 +115,7 @@ func setupInstance(instance interfaces.NetworkManager) error {
 	ri = &mixmessages.RoundInfo{
 		ID: 2,
 	}
-	if err = signature.Sign(ri, testCert); err != nil {
+	if err = signature.SignRsa(ri, testCert); err != nil {
 		return errors.Errorf("Failed to sign round info: %v", err)
 	}
 	if err = instance.GetInstance().RoundUpdate(ri); err != nil {
diff --git a/network/follow.go b/network/follow.go
index d479547ea1b360f83e06973ae4c49fa15b9008f2..a6c4008cb85d703f2034de2343cb9c6168facbd8 100644
--- a/network/follow.go
+++ b/network/follow.go
@@ -34,6 +34,7 @@ import (
 	"gitlab.com/xx_network/comms/connect"
 	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/netTime"
 	"sync/atomic"
 	"time"
 )
@@ -63,8 +64,18 @@ func (m *manager) followNetwork(report interfaces.ClientErrorReport, quitCh <-ch
 			m.follow(report, rng, m.Comms, isRunning)
 		case <-TrackTicker.C:
 			numPolls := atomic.SwapUint64(m.tracker, 0)
-			jww.INFO.Printf("Polled the network %d times in the "+
-				"last %s", numPolls, debugTrackPeriod)
+			if m.numLatencies != 0 {
+				latencyAvg := time.Nanosecond * time.Duration(m.latencySum/m.numLatencies)
+				m.latencySum, m.numLatencies = 0, 0
+
+				jww.INFO.Printf("Polled the network %d times in the "+
+					"last %s, with an average newest packet latency of %s", numPolls,
+					debugTrackPeriod, latencyAvg)
+			} else {
+				jww.INFO.Printf("Polled the network %d times in the "+
+					"last %s", numPolls, debugTrackPeriod)
+			}
+
 		}
 		if !isRunning.IsRunning() {
 			jww.ERROR.Printf("Killing network follower " +
@@ -100,6 +111,7 @@ func (m *manager) follow(report interfaces.ClientErrorReport, rng csprng.Source,
 		StartTimestamp: identity.StartRequest.UnixNano(),
 		EndTimestamp:   identity.EndRequest.UnixNano(),
 		ClientVersion:  []byte(version.String()),
+		FastPolling:    m.param.FastPolling,
 	}
 
 	result, err := m.GetSender().SendToAny(func(host *connect.Host) (interface{}, error) {
@@ -113,6 +125,9 @@ func (m *manager) follow(report interfaces.ClientErrorReport, rng csprng.Source,
 			"due to failed exit")
 		return
 	}
+
+	now := netTime.Now()
+
 	if err != nil {
 		if report != nil {
 			report(
@@ -207,6 +222,21 @@ func (m *manager) follow(report interfaces.ClientErrorReport, rng csprng.Source,
 				}
 			}
 		}
+
+		newestTS := uint64(0)
+		for i := 0; i < len(pollResp.Updates[len(pollResp.Updates)-1].Timestamps); i++ {
+			if pollResp.Updates[len(pollResp.Updates)-1].Timestamps[i] != 0 {
+				newestTS = pollResp.Updates[len(pollResp.Updates)-1].Timestamps[i]
+			}
+		}
+
+		newest := time.Unix(0, int64(newestTS))
+
+		if newest.After(now) {
+			deltaDur := newest.Sub(now)
+			m.latencySum = uint64(deltaDur)
+			m.numLatencies++
+		}
 	}
 
 	// ---- Identity Specific Round Processing -----
diff --git a/network/manager.go b/network/manager.go
index 1cf065d691b44ca061404b426af7c26df965ca40..87b35f02230429f7e41786f4ff25c9ee6c4300e3 100644
--- a/network/manager.go
+++ b/network/manager.go
@@ -47,7 +47,9 @@ type manager struct {
 	message *message.Manager
 
 	//number of polls done in a period of time
-	tracker *uint64
+	tracker      *uint64
+	latencySum   uint64
+	numLatencies uint64
 }
 
 // NewManager builds a new reception manager object using inputted key fields
@@ -56,7 +58,7 @@ func NewManager(session *storage.Session, switchboard *switchboard.Switchboard,
 	params params.Network, ndf *ndf.NetworkDefinition) (interfaces.NetworkManager, error) {
 
 	//start network instance
-	instance, err := network.NewInstance(comms.ProtoComms, ndf, nil, nil, network.None)
+	instance, err := network.NewInstance(comms.ProtoComms, ndf, nil, nil, network.None, params.FastPolling)
 	if err != nil {
 		return nil, errors.WithMessage(err, "failed to create"+
 			" client network manager")
diff --git a/network/message/critical.go b/network/message/critical.go
index 1dad92c821e756e3c89c6d013c5d78c9e09a1015..384ac9981f1dec0471b72aa3083880c26fc56382 100644
--- a/network/message/critical.go
+++ b/network/message/critical.go
@@ -80,7 +80,7 @@ func (m *Manager) criticalMessages() {
 				return
 			}
 
-			jww.INFO.Printf("Sucesfull resend of critical message "+
+			jww.INFO.Printf("Successful resend of critical message "+
 				"to %s on rounds %d", msg.Recipient, rounds)
 			critMsgs.Succeeded(msg)
 		}(msg, param)
@@ -128,7 +128,7 @@ func (m *Manager) criticalMessages() {
 				return
 			}
 
-			jww.INFO.Printf("Sucesfull resend of critical raw message "+
+			jww.INFO.Printf("Successful resend of critical raw message "+
 				"to %s (msgDigest: %s) on round %d", rid, msg.Digest(), round)
 
 			critRawMsgs.Succeeded(msg, rid)
diff --git a/network/message/sendCmix.go b/network/message/sendCmix.go
index b608e8c6e2c62ace780a8ce8391f943ac1712bb1..8f55fcf56305a239a985bf5834a398b4b3d5ebf1 100644
--- a/network/message/sendCmix.go
+++ b/network/message/sendCmix.go
@@ -223,7 +223,7 @@ func sendCmixHelper(sender *gateway.Sender, msg format.Message, recipient *id.ID
 		gwSlotResp := result.(*pb.GatewaySlotResponse)
 		if gwSlotResp.Accepted {
 			jww.INFO.Printf("Successfully sent to EphID %v (source: %s) "+
-				"in round %d", ephID.Int64(), recipient, bestRound.ID)
+				"in round %d (msgDigest: %s)", ephID.Int64(), recipient, bestRound.ID, msg.Digest())
 			return id.Round(bestRound.ID), ephID, nil
 		} else {
 			jww.FATAL.Panicf("Gateway %s returned no error, but failed "+
diff --git a/network/message/sendCmix_test.go b/network/message/sendCmix_test.go
index 28a2cdbab74a68f12ce6e45814bde8ff521adcf1..f3182a8a2407c4f29c1c615160a28fd793ab4ee6 100644
--- a/network/message/sendCmix_test.go
+++ b/network/message/sendCmix_test.go
@@ -107,7 +107,7 @@ func Test_attemptSendCmix(t *testing.T) {
 		AddressSpaceSize:           4,
 	}
 
-	if err = testutils.SignRoundInfo(ri, t); err != nil {
+	if err = testutils.SignRoundInfoRsa(ri, t); err != nil {
 		t.Errorf("Failed to sign mock round info: %v", err)
 	}
 
@@ -115,7 +115,7 @@ func Test_attemptSendCmix(t *testing.T) {
 	if err != nil {
 		t.Errorf("Failed to load a key for testing: %v", err)
 	}
-	rnd := ds.NewRound(ri, pubKey)
+	rnd := ds.NewRound(ri, pubKey, nil)
 	inst.GetWaitingRounds().Insert(rnd)
 	i := internal.Internal{
 		Session:          sess1,
diff --git a/network/message/sendE2E.go b/network/message/sendE2E.go
index 16c14701d47ead025dae9758fa4697ce6c5ea007..b09e96c4a19598e7724ccf0bd5781ff60745b3d1 100644
--- a/network/message/sendE2E.go
+++ b/network/message/sendE2E.go
@@ -114,7 +114,7 @@ func (m *Manager) SendE2E(msg message.Send, param params.E2E) ([]id.Round, e2e.M
 		return nil, e2e.MessageID{}, errors.Errorf("Failed to E2E send %v/%v sub payloads:"+
 			" %s", numFail, len(partitions), errRtn)
 	} else {
-		jww.INFO.Printf("Sucesfully E2E sent %d/%d to %s",
+		jww.INFO.Printf("Successfully E2E sent %d/%d to %s",
 			len(partitions)-numFail, len(partitions), msg.Recipient)
 	}
 
diff --git a/network/node/register.go b/network/node/register.go
index c89d2dd55371bef074a3d417f5ca05ae66d4e550..82ab2cc3d937245adbc63812d6e875bc63657845 100644
--- a/network/node/register.go
+++ b/network/node/register.go
@@ -59,6 +59,8 @@ func registerNodes(sender *gateway.Sender, session *storage.Session, rngGen *fas
 	stop *stoppable.Single, c chan network.NodeGateway) {
 	u := session.User()
 	regSignature := u.GetTransmissionRegistrationValidationSignature()
+	// Timestamp in which user has registered with permissioning
+	regTimestamp := u.GetRegistrationTimestamp().UnixNano()
 	uci := u.GetCryptographicIdentity()
 	cmix := session.Cmix()
 
@@ -71,7 +73,7 @@ func registerNodes(sender *gateway.Sender, session *storage.Session, rngGen *fas
 			t.Stop()
 			return
 		case gw := <-c:
-			err := registerWithNode(sender, comms, gw, regSignature, uci, cmix, rng)
+			err := registerWithNode(sender, comms, gw, regSignature, regTimestamp, uci, cmix, rng)
 			if err != nil {
 				jww.ERROR.Printf("Failed to register node: %+v", err)
 			}
@@ -82,8 +84,10 @@ func registerNodes(sender *gateway.Sender, session *storage.Session, rngGen *fas
 
 //registerWithNode serves as a helper for RegisterWithNodes
 // It registers a user with a specific in the client's ndf.
-func registerWithNode(sender *gateway.Sender, comms RegisterNodeCommsInterface, ngw network.NodeGateway, regSig []byte,
-	uci *user.CryptographicIdentity, store *cmix.Store, rng csprng.Source) error {
+func registerWithNode(sender *gateway.Sender, comms RegisterNodeCommsInterface, ngw network.NodeGateway,
+	regSig []byte, registrationTimestampNano int64, uci *user.CryptographicIdentity,
+	store *cmix.Store, rng csprng.Source) error {
+
 	nodeID, err := ngw.Node.GetNodeId()
 	if err != nil {
 		jww.ERROR.Println("registerWithNode() failed to decode nodeId")
@@ -118,7 +122,7 @@ func registerWithNode(sender *gateway.Sender, comms RegisterNodeCommsInterface,
 		// keys
 		transmissionHash, _ := hash.NewCMixHash()
 
-		nonce, dhPub, err := requestNonce(sender, comms, gatewayID, regSig, uci, store, rng)
+		nonce, dhPub, err := requestNonce(sender, comms, gatewayID, regSig, registrationTimestampNano, uci, store, rng)
 		if err != nil {
 			return errors.Errorf("Failed to request nonce: %+v", err)
 		}
@@ -145,8 +149,10 @@ func registerWithNode(sender *gateway.Sender, comms RegisterNodeCommsInterface,
 	return nil
 }
 
-func requestNonce(sender *gateway.Sender, comms RegisterNodeCommsInterface, gwId *id.ID, regHash []byte,
-	uci *user.CryptographicIdentity, store *cmix.Store, rng csprng.Source) ([]byte, []byte, error) {
+func requestNonce(sender *gateway.Sender, comms RegisterNodeCommsInterface, gwId *id.ID,
+	regSig []byte, registrationTimestampNano int64, uci *user.CryptographicIdentity,
+	store *cmix.Store, rng csprng.Source) ([]byte, []byte, error) {
+
 	dhPub := store.GetDHPublicKey().Bytes()
 	opts := rsa.NewDefaultOptions()
 	opts.Hash = hash.CMixHash
@@ -170,13 +176,15 @@ func requestNonce(sender *gateway.Sender, comms RegisterNodeCommsInterface, gwId
 				Salt:            uci.GetTransmissionSalt(),
 				ClientRSAPubKey: string(rsa.CreatePublicKeyPem(uci.GetTransmissionRSA().GetPublic())),
 				ClientSignedByServer: &messages.RSASignature{
-					Signature: regHash,
+					Signature: regSig,
 				},
 				ClientDHPubKey: dhPub,
 				RequestSignature: &messages.RSASignature{
 					Signature: clientSig,
 				},
 				Target: gwId.Marshal(),
+				// Timestamp in which user has registered with permissioning
+				TimeStamp: registrationTimestampNano,
 			})
 		if err != nil {
 			errMsg := fmt.Sprintf("Register: Failed requesting nonce from gateway: %+v", err)
diff --git a/permissioning/permissioning_test.go b/permissioning/permissioning_test.go
index 7f691f3a419f5a43109206da5a802b3bb2029be3..dc3e73c2e73a1872a812fb54f7ab374c8d37cf85 100644
--- a/permissioning/permissioning_test.go
+++ b/permissioning/permissioning_test.go
@@ -22,7 +22,9 @@ func TestInit(t *testing.T) {
 		t.Fatal(err)
 	}
 	def := &ndf.NetworkDefinition{
-		Registration: ndf.Registration{},
+		Registration: ndf.Registration{
+			EllipticPubKey: "MqaJJ3GjFisNRM6LRedRnooi14gepMaQxyWctXVU",
+		},
 	}
 	reg, err := Init(comms, def)
 	if err != nil {
diff --git a/permissioning/register.go b/permissioning/register.go
index 50f6c7ca603c6c73423e9b1af160bb302ee9f33e..ead58a5fcdd3856619294bab3708f1c75049487b 100644
--- a/permissioning/register.go
+++ b/permissioning/register.go
@@ -14,7 +14,8 @@ import (
 	"gitlab.com/xx_network/crypto/signature/rsa"
 )
 
-func (perm *Permissioning) Register(transmissionPublicKey, receptionPublicKey *rsa.PublicKey, registrationCode string) ([]byte, []byte, error) {
+func (perm *Permissioning) Register(transmissionPublicKey, receptionPublicKey *rsa.PublicKey,
+	registrationCode string) ([]byte, []byte, int64, error) {
 	return register(perm.comms, perm.host, transmissionPublicKey, receptionPublicKey, registrationCode)
 }
 
@@ -26,7 +27,8 @@ type registrationMessageSender interface {
 //register registers the user with optional registration code
 // Returns an error if registration fails.
 func register(comms registrationMessageSender, host *connect.Host,
-	transmissionPublicKey, receptionPublicKey *rsa.PublicKey, registrationCode string) ([]byte, []byte, error) {
+	transmissionPublicKey, receptionPublicKey *rsa.PublicKey, registrationCode string) ([]byte, []byte, int64, error) {
+
 	response, err := comms.
 		SendRegistrationMessage(host,
 			&pb.UserRegistration{
@@ -34,13 +36,14 @@ func register(comms registrationMessageSender, host *connect.Host,
 				ClientRSAPubKey:          string(rsa.CreatePublicKeyPem(transmissionPublicKey)),
 				ClientReceptionRSAPubKey: string(rsa.CreatePublicKeyPem(receptionPublicKey)),
 			})
-
 	if err != nil {
-		err = errors.WithMessage(err, "sendRegistrationMessage: Unable to contact Identity Server!")
-		return nil, nil, err
+		err = errors.Wrap(err, "sendRegistrationMessage: Unable to contact Identity Server!")
+		return nil, nil, 0, err
 	}
 	if response.Error != "" {
-		return nil, nil, errors.Errorf("sendRegistrationMessage: error handling message: %s", response.Error)
+		return nil, nil, 0, errors.Errorf("sendRegistrationMessage: error handling message: %s", response.Error)
 	}
-	return response.ClientSignedByServer.Signature, response.ClientReceptionSignedByServer.Signature, nil
+
+	return response.ClientSignedByServer.Signature,
+		response.ClientReceptionSignedByServer.Signature, response.Timestamp, nil
 }
diff --git a/permissioning/register_test.go b/permissioning/register_test.go
index 52dcb46e948b42fdd54a8f45ca6e2f751bf8a85e..02dd58b41c77ebe7a89f8cead15dc9b144b6c7dc 100644
--- a/permissioning/register_test.go
+++ b/permissioning/register_test.go
@@ -68,7 +68,7 @@ func TestRegisterWithPermissioning(t *testing.T) {
 	}
 
 	regCode := "flooble doodle"
-	sig1, sig2, err := register(&sender, sender.getHost, key.GetPublic(), key.GetPublic(), regCode)
+	sig1, sig2, _, err := register(&sender, sender.getHost, key.GetPublic(), key.GetPublic(), regCode)
 	if err != nil {
 		t.Error(err)
 	}
@@ -105,7 +105,7 @@ func TestRegisterWithPermissioning_ResponseErr(t *testing.T) {
 	var sender MockRegistrationSender
 	sender.succeedGetHost = true
 	sender.errInReply = "failure occurred on permissioning"
-	_, _, err = register(&sender, nil, key.GetPublic(), key.GetPublic(), "")
+	_, _, _, err = register(&sender, nil, key.GetPublic(), key.GetPublic(), "")
 	if err == nil {
 		t.Error("no error if registration fails on permissioning")
 	}
@@ -122,7 +122,7 @@ func TestRegisterWithPermissioning_ConnectionErr(t *testing.T) {
 	var sender MockRegistrationSender
 	sender.succeedGetHost = true
 	sender.errSendRegistration = errors.New("connection problem")
-	_, _, err = register(&sender, nil, key.GetPublic(), key.GetPublic(), "")
+	_, _, _, err = register(&sender, nil, key.GetPublic(), key.GetPublic(), "")
 	if err == nil {
 		t.Error("no error if e.g. context deadline exceeded")
 	}
diff --git a/storage/session.go b/storage/session.go
index 608068472b49517922d6a84a8a57d90f9dc0054f..053edfd224baf9a6c377cef9a3882b07b62c4fde 100644
--- a/storage/session.go
+++ b/storage/session.go
@@ -12,6 +12,7 @@ package storage
 import (
 	"sync"
 	"testing"
+	"time"
 
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
@@ -318,6 +319,13 @@ func InitTestingSession(i interface{}) *Session {
 	}
 	u.SetTransmissionRegistrationValidationSignature([]byte("sig"))
 	u.SetReceptionRegistrationValidationSignature([]byte("sig"))
+	testTime, err := time.Parse(time.RFC3339,
+		"2012-12-21T22:08:41+00:00")
+	if err != nil {
+		jww.FATAL.Panicf("Could not parse precanned time: %v", err.Error())
+	}
+	u.SetRegistrationTimestamp(testTime.UnixNano())
+
 	s.user = u
 	cmixGrp := cyclic.NewGroup(
 		large.NewIntFromString("9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48"+
diff --git a/storage/user.go b/storage/user.go
index a443d81cb2f052445a2b24a0a6becf9da0a2774b..74552020661c987b465031e12b6bf84d69575910 100644
--- a/storage/user.go
+++ b/storage/user.go
@@ -14,17 +14,18 @@ func (s *Session) GetUser() user.User {
 	defer s.mux.RUnlock()
 	ci := s.user.GetCryptographicIdentity()
 	return user.User{
-		TransmissionID:   ci.GetTransmissionID().DeepCopy(),
-		TransmissionSalt: copySlice(ci.GetTransmissionSalt()),
-		TransmissionRSA:  ci.GetTransmissionRSA(),
-		ReceptionID:      ci.GetReceptionID().DeepCopy(),
-		ReceptionSalt:    copySlice(ci.GetReceptionSalt()),
-		ReceptionRSA:     ci.GetReceptionRSA(),
-		Precanned:        ci.IsPrecanned(),
-		CmixDhPrivateKey: s.cmix.GetDHPrivateKey().DeepCopy(),
-		CmixDhPublicKey:  s.cmix.GetDHPublicKey().DeepCopy(),
-		E2eDhPrivateKey:  s.e2e.GetDHPrivateKey().DeepCopy(),
-		E2eDhPublicKey:   s.e2e.GetDHPublicKey().DeepCopy(),
+		TransmissionID:        ci.GetTransmissionID().DeepCopy(),
+		TransmissionSalt:      copySlice(ci.GetTransmissionSalt()),
+		TransmissionRSA:       ci.GetTransmissionRSA(),
+		ReceptionID:           ci.GetReceptionID().DeepCopy(),
+		RegistrationTimestamp: s.user.GetRegistrationTimestamp(),
+		ReceptionSalt:         copySlice(ci.GetReceptionSalt()),
+		ReceptionRSA:          ci.GetReceptionRSA(),
+		Precanned:             ci.IsPrecanned(),
+		CmixDhPrivateKey:      s.cmix.GetDHPrivateKey().DeepCopy(),
+		CmixDhPublicKey:       s.cmix.GetDHPublicKey().DeepCopy(),
+		E2eDhPrivateKey:       s.e2e.GetDHPrivateKey().DeepCopy(),
+		E2eDhPublicKey:        s.e2e.GetDHPublicKey().DeepCopy(),
 	}
 
 }
diff --git a/storage/user/regValidationSig.go b/storage/user/registation.go
similarity index 70%
rename from storage/user/regValidationSig.go
rename to storage/user/registation.go
index 7440500fc680e2aee821ac761f47c8d9b201f40a..4da19b4cd0faf8e83fe22ad2e177afb8d8109897 100644
--- a/storage/user/regValidationSig.go
+++ b/storage/user/registation.go
@@ -8,14 +8,18 @@
 package user
 
 import (
+	"encoding/binary"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/xx_network/primitives/netTime"
+	"time"
 )
 
 const currentRegValidationSigVersion = 0
+const registrationTimestampVersion = 0
 const transmissionRegValidationSigKey = "transmissionRegistrationValidationSignature"
 const receptionRegValidationSigKey = "receptionRegistrationValidationSignature"
+const registrationTimestampKey = "registrationTimestamp"
 
 // Returns the transmission Identity Validation Signature stored in RAM. May return
 // nil of no signature is stored
@@ -33,6 +37,13 @@ func (u *User) GetReceptionRegistrationValidationSignature() []byte {
 	return u.receptionRegValidationSig
 }
 
+// Returns the registration timestamp stored in RAM as
+func (u *User) GetRegistrationTimestamp() time.Time {
+	u.rvsMux.RLock()
+	defer u.rvsMux.RUnlock()
+	return u.registrationTimestamp
+}
+
 // Loads the transmission Identity Validation Signature if it exists in the ekv
 func (u *User) loadTransmissionRegistrationValidationSignature() {
 	u.rvsMux.Lock()
@@ -55,6 +66,18 @@ func (u *User) loadReceptionRegistrationValidationSignature() {
 	u.rvsMux.Unlock()
 }
 
+// Loads the registration timestamp if it exists in the ekv
+func (u *User) loadRegistrationTimestamp() {
+	u.rvsMux.Lock()
+	obj, err := u.kv.Get(registrationTimestampKey,
+		registrationTimestampVersion)
+	if err == nil {
+		tsNano := binary.BigEndian.Uint64(obj.Data)
+		u.registrationTimestamp = time.Unix(0, int64(tsNano))
+	}
+	u.rvsMux.Unlock()
+}
+
 // Sets the Identity Validation Signature if it is not set and stores it in
 // the ekv
 func (u *User) SetTransmissionRegistrationValidationSignature(b []byte) {
@@ -108,3 +131,34 @@ func (u *User) SetReceptionRegistrationValidationSignature(b []byte) {
 
 	u.receptionRegValidationSig = b
 }
+
+// Sets the Registration Timestamp if it is not set and stores it in
+// the ekv
+func (u *User) SetRegistrationTimestamp(tsNano int64) {
+	u.rvsMux.Lock()
+	defer u.rvsMux.Unlock()
+
+	//check if the signature already exists
+	if !u.registrationTimestamp.IsZero() {
+		jww.FATAL.Panicf("cannot overwrite existing registration timestamp")
+	}
+
+	// Serialize the timestamp
+	tsBytes := make([]byte, 8)
+	binary.BigEndian.PutUint64(tsBytes, uint64(tsNano))
+
+	obj := &versioned.Object{
+		Version:   currentRegValidationSigVersion,
+		Timestamp: netTime.Now(),
+		Data:      tsBytes,
+	}
+
+	err := u.kv.Set(registrationTimestampKey,
+		registrationTimestampVersion, obj)
+	if err != nil {
+		jww.FATAL.Panicf("Failed to store the reception timestamp: %s", err)
+	}
+
+	u.registrationTimestamp = time.Unix(0, tsNano)
+
+}
diff --git a/storage/user/regValidationSig_test.go b/storage/user/registation_test.go
similarity index 64%
rename from storage/user/regValidationSig_test.go
rename to storage/user/registation_test.go
index 68a69f60c8a8dca24161a4ec8bc9721d096aa6a9..31c6d3d1ee67f4e81fddd4a5822a18d0ad4d7ccf 100644
--- a/storage/user/regValidationSig_test.go
+++ b/storage/user/registation_test.go
@@ -9,12 +9,14 @@ package user
 
 import (
 	"bytes"
+	"encoding/binary"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/crypto/signature/rsa"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 	"testing"
+	"time"
 )
 
 // Test User GetRegistrationValidationSignature function
@@ -137,3 +139,88 @@ func TestUser_loadRegistrationValidationSignature(t *testing.T) {
 		t.Errorf("Expected sig did not match loaded.  Expected: %+v, Received: %+v", sig, u.receptionRegValidationSig)
 	}
 }
+
+// Test User's getter/setter functions for TimeStamp
+func TestUser_GetRegistrationTimestamp(t *testing.T) {
+	kv := versioned.NewKV(make(ekv.Memstore))
+	uid := id.NewIdFromString("test", id.User, t)
+	salt := []byte("salt")
+	u, err := NewUser(kv, uid, uid, salt, salt, &rsa.PrivateKey{}, &rsa.PrivateKey{}, false)
+	if err != nil || u == nil {
+		t.Errorf("Failed to create new user: %+v", err)
+	}
+
+	testTime, err := time.Parse(time.RFC3339,
+		"2012-12-21T22:08:41+00:00")
+	if err != nil {
+		t.Fatalf("Could not parse precanned time: %v", err.Error())
+	}
+
+	// Test that User has been modified for timestamp
+	u.SetRegistrationTimestamp(testTime.UnixNano())
+	if !testTime.Equal(u.registrationTimestamp) {
+		t.Errorf("SetRegistrationTimestamp did not set user's timestamp value."+
+			"\n\tExpected: %s\n\tReceieved: %s", testTime.String(), u.registrationTimestamp)
+	}
+
+	// Pull timestamp from kv
+	obj, err := u.kv.Get(registrationTimestampKey, registrationTimestampVersion)
+	if err != nil {
+		t.Errorf("Failed to get reg vaildation signature key: %+v", err)
+	}
+
+	// Check if kv data is expected
+	unixNano := binary.BigEndian.Uint64(obj.Data)
+	if testTime.UnixNano() != int64(unixNano) {
+		t.Errorf("Timestamp pulled from kv was not expected."+
+			"\n\tExpected: %d\n\tReceieved: %d", testTime.UnixNano(), unixNano)
+	}
+
+	if testTime.UnixNano() != u.GetRegistrationTimestamp().UnixNano() {
+		t.Errorf("Timestamp from GetRegistrationTimestampNano was not expected."+
+			"\n\tExpected: %d\n\tReceieved: %d", testTime.UnixNano(), u.GetRegistrationTimestamp().UnixNano())
+	}
+
+	if !testTime.Equal(u.GetRegistrationTimestamp()) {
+		t.Errorf("Timestamp from GetRegistrationTimestamp was not expected."+
+			"\n\tExpected: %s\n\tReceieved: %s", testTime, u.GetRegistrationTimestamp())
+
+	}
+
+}
+
+// Test loading registrationTimestamp from the KV store
+func TestUser_loadRegistrationTimestamp(t *testing.T) {
+	kv := versioned.NewKV(make(ekv.Memstore))
+	uid := id.NewIdFromString("test", id.User, t)
+	salt := []byte("salt")
+	u, err := NewUser(kv, uid, uid, salt, salt, &rsa.PrivateKey{}, &rsa.PrivateKey{}, false)
+	if err != nil || u == nil {
+		t.Errorf("Failed to create new user: %+v", err)
+	}
+
+	testTime, err := time.Parse(time.RFC3339,
+		"2012-12-21T22:08:41+00:00")
+	if err != nil {
+		t.Fatalf("Could not parse precanned time: %v", err.Error())
+	}
+
+	data := make([]byte, 8)
+	binary.BigEndian.PutUint64(data, uint64(testTime.UnixNano()))
+	vo := &versioned.Object{
+		Version:   currentRegValidationSigVersion,
+		Timestamp: netTime.Now(),
+		Data:      data,
+	}
+	err = kv.Set(registrationTimestampKey,
+		registrationTimestampVersion, vo)
+	if err != nil {
+		t.Errorf("Failed to set reg validation sig key in kv store: %+v", err)
+	}
+
+	u.loadRegistrationTimestamp()
+	if !testTime.Equal(u.registrationTimestamp) {
+		t.Errorf("SetRegistrationTimestamp did not set user's timestamp value."+
+			"\n\tExpected: %s\n\tReceieved: %s", testTime.String(), u.registrationTimestamp)
+	}
+}
diff --git a/storage/user/user.go b/storage/user/user.go
index a55830ff131620f7f9f499b2a6932d616675ccda..c1779524245cd729df731243837d772ddf7b2c03 100644
--- a/storage/user/user.go
+++ b/storage/user/user.go
@@ -13,6 +13,7 @@ import (
 	"gitlab.com/xx_network/crypto/signature/rsa"
 	"gitlab.com/xx_network/primitives/id"
 	"sync"
+	"time"
 )
 
 type User struct {
@@ -20,7 +21,9 @@ type User struct {
 
 	transmissionRegValidationSig []byte
 	receptionRegValidationSig    []byte
-	rvsMux                       sync.RWMutex
+	// Time in which user registered with the network
+	registrationTimestamp time.Time
+	rvsMux                sync.RWMutex
 
 	username    string
 	usernameMux sync.RWMutex
@@ -48,6 +51,7 @@ func LoadUser(kv *versioned.KV) (*User, error) {
 	u.loadTransmissionRegistrationValidationSignature()
 	u.loadReceptionRegistrationValidationSignature()
 	u.loadUsername()
+	u.loadRegistrationTimestamp()
 
 	return u, nil
 }
diff --git a/ud/register.go b/ud/register.go
index 764b8a2b96ee03e75b3eba91e44a2f31f4590f3b..b46f99a09fd6e686c2293b35a54147d7292d58cb 100644
--- a/ud/register.go
+++ b/ud/register.go
@@ -48,7 +48,8 @@ func (m *Manager) register(username string, comm registerUserComms) error {
 			DhPubKey: m.storage.E2e().GetDHPublicKey().Bytes(),
 			Salt:     cryptoUser.GetReceptionSalt(),
 		},
-		UID: cryptoUser.GetReceptionID().Marshal(),
+		UID:       cryptoUser.GetReceptionID().Marshal(),
+		Timestamp: user.GetRegistrationTimestamp().UnixNano(),
 	}
 
 	// Sign the identity data and add to user registration message