diff --git a/go.mod b/go.mod
index 1e46cd11206125e012fcfe43d80d2b75bbe6d845..a880cd60b6926158e127e13186990479a0d30aa7 100644
--- a/go.mod
+++ b/go.mod
@@ -5,19 +5,24 @@ go 1.13
 require (
 	github.com/golang-collections/collections v0.0.0-20130729185459-604e922904d3
 	github.com/golang/protobuf v1.4.2
+	github.com/magiconair/properties v1.8.4 // indirect
+	github.com/mitchellh/mapstructure v1.3.3 // indirect
+	github.com/pelletier/go-toml v1.8.1 // indirect
 	github.com/pkg/errors v0.9.1
+	github.com/spf13/afero v1.4.0 // indirect
 	github.com/spf13/cobra v1.0.0
 	github.com/spf13/jwalterweatherman v1.1.0
-	github.com/spf13/viper v1.6.2
-	gitlab.com/elixxir/comms v0.0.0-20200925154004-716284cff8cb
-	gitlab.com/elixxir/crypto v0.0.0-20200921195205-bca0178268ec
-	gitlab.com/elixxir/ekv v0.1.2-0.20200917221437-9f9630da030a
+	github.com/spf13/viper v1.7.1
+	gitlab.com/elixxir/comms v0.0.0-20200924225440-76e02f95fb92
+	gitlab.com/elixxir/crypto v0.0.0-20201002151111-280700c6e774
+	gitlab.com/elixxir/ekv v0.1.3
 	gitlab.com/elixxir/primitives v0.0.0-20200915190719-f4586ec93f50
-	gitlab.com/xx_network/comms v0.0.0-20200925191822-08c0799a24a6
+	gitlab.com/xx_network/comms v0.0.0-20200924225518-0c867207b1e6
 	gitlab.com/xx_network/crypto v0.0.0-20200812183430-c77a5281c686
-	gitlab.com/xx_network/primitives v0.0.0-20200812183720-516a65a4a9b2
-	golang.org/x/sys v0.0.0-20200918174421-af09f7315aff // indirect
+	gitlab.com/xx_network/primitives v0.0.0-20200915204206-eb0287ed0031
+	golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d // indirect
 	google.golang.org/protobuf v1.25.0
+	gopkg.in/ini.v1 v1.61.0 // indirect
 )
 
 replace google.golang.org/grpc => github.com/grpc/grpc-go v1.27.1
diff --git a/go.sum b/go.sum
index 26d149605572d1aaff97f325d6e5943d84c2dc8c..78e7367fc2b229e1870cae6bcac38473466206f4 100644
--- a/go.sum
+++ b/go.sum
@@ -1,16 +1,36 @@
+cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
+cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=
+cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=
+cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
+cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
+cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
+cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
+cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
+cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
+cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
+dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
 github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
 github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
+github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
+github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
+github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
+github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
 github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
 github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
+github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
 github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
+github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
 github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
 github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
 github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
@@ -22,11 +42,13 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm
 github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
 github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
 github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
+github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
 github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
 github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
@@ -39,6 +61,8 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekf
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
 github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
 github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@@ -52,6 +76,7 @@ github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0
 github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
 github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0=
 github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
+github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
 github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
 github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -60,26 +85,55 @@ github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4=
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
+github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
+github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
+github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
 github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0=
 github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
+github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
 github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
 github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
 github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
 github.com/grpc/grpc-go v1.27.1 h1:EluyjU5nlbuNJSEktNl600PIpzbO2OcvZWfWV1jFvKM=
 github.com/grpc/grpc-go v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
+github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
+github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
+github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
+github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
+github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
+github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
+github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
+github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
+github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
+github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
+github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
+github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90=
+github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
+github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
 github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
 github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
+github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
+github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
+github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
+github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
+github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
+github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
 github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
+github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
@@ -89,23 +143,44 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4=
 github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
+github.com/magiconair/properties v1.8.4 h1:8KGKTcQQGm0Kv7vEbKFErAoAOFyyacLStRtQSeYtvkY=
+github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
+github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
+github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
+github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
+github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI=
+github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg=
+github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY=
+github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
 github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
 github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
+github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
+github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
+github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
+github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
+github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
 github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
 github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
+github.com/pelletier/go-toml v1.8.1 h1:1Nf83orprkJyknT6h7zbuEGUEjcyVlCxSUGTENmNCRM=
+github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
 github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
 github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso=
 github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -117,7 +192,10 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
 github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
 github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
 github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
 github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
+github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
 github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
@@ -130,6 +208,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO
 github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
 github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/afero v1.4.0 h1:jsLTaI1zwYO3vjrzHalkVcIHXTNmdQFepW4OI8H3+x8=
+github.com/spf13/afero v1.4.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
 github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
@@ -144,9 +224,13 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An
 github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
 github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E=
 github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
+github.com/spf13/viper v1.7.1 h1:pM5oEahlgWv/WnHXpgbKz7iLIxRf65tye2Ci+XFK5sk=
+github.com/spf13/viper v1.7.1/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
 github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
@@ -158,32 +242,96 @@ github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGr
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 github.com/zeebo/assert v0.0.0-20181109011804-10f827ce2ed6/go.mod h1:yssERNPivllc1yU3BvpjYI5BUW+zglcz6QWqeVRL5t0=
-github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
 github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
 github.com/zeebo/blake3 v0.0.4 h1:vtZ4X8B2lKXZFg2Xyg6Wo36mvmnJvc2VQYTtA4RDCkI=
 github.com/zeebo/blake3 v0.0.4/go.mod h1:YOZo8A49yNqM0X/Y+JmDUZshJWLt1laHsNSn5ny2i34=
-github.com/zeebo/pcg v0.0.0-20181207190024-3cdc6b625a05 h1:4pW5fMvVkrgkMXdvIsVRRTs69DWYA8uNNQsu1stfVKU=
 github.com/zeebo/pcg v0.0.0-20181207190024-3cdc6b625a05/go.mod h1:Gr+78ptB0MwXxm//LBaEvBiaXY7hXJ6KGe2V32X2F6E=
 gitlab.com/elixxir/client v1.5.0/go.mod h1:/uVTzYDhKaGgN8LGGh1sSsxbh+BrpVi1X8VToAT3DfA=
 gitlab.com/elixxir/comms v0.0.0-20200707210150-b8ebd0951d23/go.mod h1:OsWMZ1O/R9fOkm+PoHnR3rkXfFtipGoPs73FuKuurHY=
+gitlab.com/elixxir/comms v0.0.0-20200810165153-3039323b5656 h1:A5S3E7EPL95s3+PGhgAiwnMaa7VcWj8/RtBur3lxdOw=
+gitlab.com/elixxir/comms v0.0.0-20200810165153-3039323b5656/go.mod h1:EeS1z5wXKrnWOvR0dJlVNVv8OzuiGJz7fa6LyUeN6Q0=
+gitlab.com/elixxir/comms v0.0.0-20200813225502-e879259ca741 h1:yIjgre8xSDpnhJkDzTr1lgR7NC1bPWCk2Sgn8udiS2A=
+gitlab.com/elixxir/comms v0.0.0-20200813225502-e879259ca741/go.mod h1:hEi6dhcR1v6TGcp3tBy+QFuE25zux206xymuB+PpUqs=
+gitlab.com/elixxir/comms v0.0.0-20200825195434-49150e0605d8 h1:6kwb++vm3XUf+AoR18bDfqNsKR8qghFkDERYmVAlwsU=
+gitlab.com/elixxir/comms v0.0.0-20200825195434-49150e0605d8/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc=
+gitlab.com/elixxir/comms v0.0.0-20200827170208-d1f872422b7e h1:BEBxLOW6yMdT53rBvxlDifsGSPYKA88K233DOpKY5Zw=
+gitlab.com/elixxir/comms v0.0.0-20200827170208-d1f872422b7e/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc=
+gitlab.com/elixxir/comms v0.0.0-20200827193018-c0911a1a1ec0 h1:C0P5VqrgGcTuV9kCicxakHLSUFN3qNk55O/nrBmY0fk=
+gitlab.com/elixxir/comms v0.0.0-20200827193018-c0911a1a1ec0/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc=
+gitlab.com/elixxir/comms v0.0.0-20200828220824-6e9c8abca9bc h1:+Plp0oXKNTvHUZkoYusFyLELlyXgAKn3O5I3389xv+A=
+gitlab.com/elixxir/comms v0.0.0-20200828220824-6e9c8abca9bc/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc=
+gitlab.com/elixxir/comms v0.0.0-20200901233126-5b6d9c7088c7 h1:BQpz37TSl+ndWKPpA/Qqmja0YYRS+lKgRUAJ2j1cpbs=
+gitlab.com/elixxir/comms v0.0.0-20200901233126-5b6d9c7088c7/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc=
+gitlab.com/elixxir/comms v0.0.0-20200903181126-c92d7a304999 h1:fxrqseawjJ2q6Z3NZyYLKAqld1+ECsDkrgJdmIieivM=
+gitlab.com/elixxir/comms v0.0.0-20200903181126-c92d7a304999/go.mod h1:HW3Ige10aeJeyb2fcQ/YOBPiyzY/4jHau1Cj6/1WBHc=
+gitlab.com/elixxir/comms v0.0.0-20200909214857-b106ce82d9e8 h1:y+0aElewUD0ceZHvf96+s8oUZnfBMD9aflOBztMNlZ0=
+gitlab.com/elixxir/comms v0.0.0-20200909214857-b106ce82d9e8/go.mod h1:ZMwe9xZbPY1s81CVvy51hh+96b/supA797uxXEJJqRE=
+gitlab.com/elixxir/comms v0.0.0-20200915163543-c2f080316df8 h1:qLOm7w/+Uco7jOJmZ1HjPGC3uwHu3Z21OCMb+hKfd20=
+gitlab.com/elixxir/comms v0.0.0-20200915163543-c2f080316df8/go.mod h1:O5e4ISYYofsrrVD5Qzt1Ah8z0Fr2YqTXFwUJjmAiSjk=
+gitlab.com/elixxir/comms v0.0.0-20200915164538-d15120cc8fa5 h1:QnIlpEi6dln6MIPvcgkOVV9+OFWP6HCSmjys8UgAoho=
+gitlab.com/elixxir/comms v0.0.0-20200915164538-d15120cc8fa5/go.mod h1:O5e4ISYYofsrrVD5Qzt1Ah8z0Fr2YqTXFwUJjmAiSjk=
+gitlab.com/elixxir/comms v0.0.0-20200916212207-60e7bd5b0913 h1:p4TLPPaMysV//lOJUZEOtfpOB/7wbsFEWFZMAwjnPFE=
+gitlab.com/elixxir/comms v0.0.0-20200916212207-60e7bd5b0913/go.mod h1:yBEsOZSPyJQJvDbtlQ5L8ydy1JRgVlRoNgMDy9koQcE=
+gitlab.com/elixxir/comms v0.0.0-20200917172539-929fc227eb0c h1:go7/RknV7646Ie+nmQXZAa/aJ5wZBn5bpAYRB+tPens=
+gitlab.com/elixxir/comms v0.0.0-20200917172539-929fc227eb0c/go.mod h1:yBEsOZSPyJQJvDbtlQ5L8ydy1JRgVlRoNgMDy9koQcE=
 gitlab.com/elixxir/comms v0.0.0-20200917221445-8a509560122a/go.mod h1:L2Va13j2AbQkpkveOQmNzrQD37uI5NKeBhYH+LWMOx0=
-gitlab.com/elixxir/comms v0.0.0-20200925154004-716284cff8cb h1:hLyB/uL9aBxf916FriYu9/XRppwsoeTeqjFcZtCZH2M=
-gitlab.com/elixxir/comms v0.0.0-20200925154004-716284cff8cb/go.mod h1:3i4o6ie4LFC+EVN68l9tdt9JxJlAd3+pNNnKBFubKSg=
+gitlab.com/elixxir/comms v0.0.0-20200921200427-5955a0a798b9 h1:skzHNWCMh+T7Cn58/88Mikg2R8KnSWfzLV0w7SnerOs=
+gitlab.com/elixxir/comms v0.0.0-20200921200427-5955a0a798b9/go.mod h1:uRr8j6yTjCslxZxbRe6k4ixACu9gAeF61JZH36OFFa0=
+gitlab.com/elixxir/comms v0.0.0-20200922163657-3e723b7170f6 h1:dFgfdATZuiPybonCBh0s4HeLB8Qw3Zm9EoLDRh2Eaaw=
+gitlab.com/elixxir/comms v0.0.0-20200922163657-3e723b7170f6/go.mod h1:yBEsOZSPyJQJvDbtlQ5L8ydy1JRgVlRoNgMDy9koQcE=
+gitlab.com/elixxir/comms v0.0.0-20200924072138-2e2709483d89 h1:PQalM7pnCRzZRKvdzJ6Jwz6e8bPR9H4CURzAwqYnJPE=
+gitlab.com/elixxir/comms v0.0.0-20200924072138-2e2709483d89/go.mod h1:uRr8j6yTjCslxZxbRe6k4ixACu9gAeF61JZH36OFFa0=
+gitlab.com/elixxir/comms v0.0.0-20200924210331-d7903c023fa6 h1:ctVsHyiabgRls3esApbBemDwmQ/a0CramEmZt9RCQb8=
+gitlab.com/elixxir/comms v0.0.0-20200924210331-d7903c023fa6/go.mod h1:9+Jj7K8HOTgBjPuiP69VtTKTv7GvAK6bWlh4lgMAqrk=
+gitlab.com/elixxir/comms v0.0.0-20200924225440-76e02f95fb92 h1:KwqVzHpqYg1l1/KG6uRqnl7HBgvrzuknMVCeEvRsbow=
+gitlab.com/elixxir/comms v0.0.0-20200924225440-76e02f95fb92/go.mod h1:3i4o6ie4LFC+EVN68l9tdt9JxJlAd3+pNNnKBFubKSg=
 gitlab.com/elixxir/crypto v0.0.0-20200707005343-97f868cbd930/go.mod h1:LHBAaEf48a0/AjU118rjoworH0LgXifhAqmNX3ZRvME=
 gitlab.com/elixxir/crypto v0.0.0-20200731174640-0503cf80524a/go.mod h1:LHBAaEf48a0/AjU118rjoworH0LgXifhAqmNX3ZRvME=
 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.0-20200805174804-bdf909f2a16d/go.mod h1:cu6uNoANVLV0J6HyTL6KqVtVyh9SHU1RjJhytYlsbVQ=
+gitlab.com/elixxir/crypto v0.0.0-20200806211835-b8ce4472f399 h1:U0oQ0cZeq1Wnv+MxZcny3RkMBONphpc1ambIgGbWovs=
+gitlab.com/elixxir/crypto v0.0.0-20200806211835-b8ce4472f399/go.mod h1:LthCESQ1AfV1H26URYL9kr+XgXXCE7JfEEPpomFPxIo=
 gitlab.com/elixxir/crypto v0.0.0-20200811195343-de268a55c7c4 h1:KlaR5JBxj3oSxSsL3Rax2Rt494sxldM0hxzlr+fBy34=
 gitlab.com/elixxir/crypto v0.0.0-20200811195343-de268a55c7c4/go.mod h1:LthCESQ1AfV1H26URYL9kr+XgXXCE7JfEEPpomFPxIo=
+gitlab.com/elixxir/crypto v0.0.0-20200819222807-20573ff0ff99 h1:eC5/rPn5ubXkvpth/xeayhkCUcGsBbxnxj7cjJ6vgic=
+gitlab.com/elixxir/crypto v0.0.0-20200819222807-20573ff0ff99/go.mod h1:pMageInOuHAQRZXnAD9yQMjhELcxb54bx4+NPT6K6tQ=
+gitlab.com/elixxir/crypto v0.0.0-20200819231654-17c3bcbe322f h1:enLfJCcYwpJGTaS9CXZlZEXiJfBv+ruo9qj4y2PKkHk=
+gitlab.com/elixxir/crypto v0.0.0-20200819231654-17c3bcbe322f/go.mod h1:pMageInOuHAQRZXnAD9yQMjhELcxb54bx4+NPT6K6tQ=
+gitlab.com/elixxir/crypto v0.0.0-20200820001855-d8ff33b65ab5 h1:iZ8A3KnSxtI+WsMOvM7GcDhrb5l8jM+xYlT4VGUJgiw=
+gitlab.com/elixxir/crypto v0.0.0-20200820001855-d8ff33b65ab5/go.mod h1:pMageInOuHAQRZXnAD9yQMjhELcxb54bx4+NPT6K6tQ=
+gitlab.com/elixxir/crypto v0.0.0-20200820010132-199706584933 h1:A+wWm+OmGAUi4lnIqZUn6LtYguuO+wdLI5OOLwHqr5I=
+gitlab.com/elixxir/crypto v0.0.0-20200820010132-199706584933/go.mod h1:pMageInOuHAQRZXnAD9yQMjhELcxb54bx4+NPT6K6tQ=
+gitlab.com/elixxir/crypto v0.0.0-20200826022234-44afcd036724 h1:9QUjB0U+fuAhMFWd6YFJVmmND0VEvxoxIa41PTtxu+E=
+gitlab.com/elixxir/crypto v0.0.0-20200826022234-44afcd036724/go.mod h1:xELLVpaOMc4c14h6Lh3LlD++KYdEihWtRkHQI0FjjXc=
+gitlab.com/elixxir/crypto v0.0.0-20200826034538-c67fec536436 h1:NvymTKdu5Zjf1tMpI6/TDvfok3xJx6EIrI3ZMWzmWx0=
+gitlab.com/elixxir/crypto v0.0.0-20200826034538-c67fec536436/go.mod h1:xELLVpaOMc4c14h6Lh3LlD++KYdEihWtRkHQI0FjjXc=
+gitlab.com/elixxir/crypto v0.0.0-20200827170914-14227f20900c h1:1vkxQ0Ol/Kr6szWaa8mMcJXW+Dqy73DOarJPswrzb3Q=
+gitlab.com/elixxir/crypto v0.0.0-20200827170914-14227f20900c/go.mod h1:D65u4dPjMLSHiENn7fvnleWUcuuSeT48Ttw760Wt3xQ=
+gitlab.com/elixxir/crypto v0.0.0-20200907171019-008a9d4aa264 h1:8jk4yHw15PpjTPHMpHo5g7io/qp+ryHBxe6S8vllfLs=
+gitlab.com/elixxir/crypto v0.0.0-20200907171019-008a9d4aa264/go.mod h1:zUczcFuZGqLchDX1sjgBo189soeDK2p5Mx+GNNrkTLI=
 gitlab.com/elixxir/crypto v0.0.0-20200915165059-c7f41bbc86b4 h1:Y9xWVPUD/cf0dWKphKWg7dRdEjDgqoHXZLhqOMOs9Ac=
 gitlab.com/elixxir/crypto v0.0.0-20200915165059-c7f41bbc86b4/go.mod h1:LthCESQ1AfV1H26URYL9kr+XgXXCE7JfEEPpomFPxIo=
+gitlab.com/elixxir/crypto v0.0.0-20200915172523-b2f2c63560c9 h1:omuo67rgWzlorzLlQQumUkES1w3M5elKFq4PmB+HjJw=
+gitlab.com/elixxir/crypto v0.0.0-20200915172523-b2f2c63560c9/go.mod h1:zUczcFuZGqLchDX1sjgBo189soeDK2p5Mx+GNNrkTLI=
+gitlab.com/elixxir/crypto v0.0.0-20200915211245-8a519dfcc38d h1:6D2r42dFuUm96KjeNYH7XzRy8l+8rbl8G5IZGdVfjOI=
+gitlab.com/elixxir/crypto v0.0.0-20200915211245-8a519dfcc38d/go.mod h1:zUczcFuZGqLchDX1sjgBo189soeDK2p5Mx+GNNrkTLI=
+gitlab.com/elixxir/crypto v0.0.0-20200917184612-bb2ad1c493ce h1:g8/MABMbpVUJOn2BMhZJo8Pkee4YVSriFoV5po0TDkY=
+gitlab.com/elixxir/crypto v0.0.0-20200917184612-bb2ad1c493ce/go.mod h1:zUczcFuZGqLchDX1sjgBo189soeDK2p5Mx+GNNrkTLI=
+gitlab.com/elixxir/crypto v0.0.0-20200921191117-583f263ab715 h1:1eMAfJ1uyOVU8O3JXQSBrVYt1CLMRUBSjYYzVPI+uO0=
+gitlab.com/elixxir/crypto v0.0.0-20200921191117-583f263ab715/go.mod h1:1P3IMJ6i3L+5si0PiMvoo/qQXMsEhNVjn0yMUrm3eiA=
 gitlab.com/elixxir/crypto v0.0.0-20200921195205-bca0178268ec h1:8dnRUCSNz7knf+K5OvmEwY181aPp5ErseJogEwgS6dY=
 gitlab.com/elixxir/crypto v0.0.0-20200921195205-bca0178268ec/go.mod h1:1P3IMJ6i3L+5si0PiMvoo/qQXMsEhNVjn0yMUrm3eiA=
+gitlab.com/elixxir/crypto v0.0.0-20201001175928-ce7312789eb7 h1:bmi0wc0m9qq+5aEiBiN+KzG87fQiLL5YJy9wJ9BpYZY=
+gitlab.com/elixxir/crypto v0.0.0-20201001175928-ce7312789eb7/go.mod h1:1P3IMJ6i3L+5si0PiMvoo/qQXMsEhNVjn0yMUrm3eiA=
+gitlab.com/elixxir/crypto v0.0.0-20201002151111-280700c6e774 h1:Ph3OiDgRQJ5Ac9VnFiv/Dk4COw2+jUjGnF7Cal5Q5W4=
+gitlab.com/elixxir/crypto v0.0.0-20201002151111-280700c6e774/go.mod h1:1P3IMJ6i3L+5si0PiMvoo/qQXMsEhNVjn0yMUrm3eiA=
 gitlab.com/elixxir/ekv v0.0.0-20200729182028-159355ea5842 h1:m1zDQ6UadpuMnV7nvnyR+DUXE3AisRnVjajTb1xZE4c=
 gitlab.com/elixxir/ekv v0.0.0-20200729182028-159355ea5842/go.mod h1:bXY0kgbV5BHYda4YY5/hiG5bjimGK+R3PYub5yM9C/s=
-gitlab.com/elixxir/ekv v0.1.2-0.20200917221437-9f9630da030a h1:QLH4VNLrI+8Spd8da41+biA02EIAhL+81dZ3hXelT+U=
-gitlab.com/elixxir/ekv v0.1.2-0.20200917221437-9f9630da030a/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4=
+gitlab.com/elixxir/ekv v0.1.1 h1:Em3rF8sv+tNbQGXbcpYzAS2blWRAP708JGhYlkN74Kg=
+gitlab.com/elixxir/ekv v0.1.1/go.mod h1:bXY0kgbV5BHYda4YY5/hiG5bjimGK+R3PYub5yM9C/s=
+gitlab.com/elixxir/ekv v0.1.3 h1:OE+LBMIhjGUMwc6hHJzYvEPNJQV7t1vMnJyIgxUMUo8=
+gitlab.com/elixxir/ekv v0.1.3/go.mod h1:e6WPUt97taFZe5PFLPb1Dupk7tqmDCTQu1kkstqJvw4=
 gitlab.com/elixxir/primitives v0.0.0-20200706165052-9fe7a4fb99a3/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
 gitlab.com/elixxir/primitives v0.0.0-20200708185800-a06e961280e6/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
 gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
@@ -192,19 +340,34 @@ gitlab.com/elixxir/primitives v0.0.0-20200804182913-788f47bded40/go.mod h1:tzdFF
 gitlab.com/elixxir/primitives v0.0.0-20200804231232-ad79a9e8f113/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc=
 gitlab.com/elixxir/primitives v0.0.0-20200805174810-86b366d1dd2d/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc=
 gitlab.com/elixxir/primitives v0.0.0-20200812191102-31c01f08b4dc/go.mod h1:pJx2DZk9s8vVMnLN7x0hIPngDjbNSdOP6kk3RLlRxHg=
+gitlab.com/elixxir/primitives v0.0.0-20200907165319-16ed0124890b/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2YKnw5c+LJCE=
 gitlab.com/elixxir/primitives v0.0.0-20200915190719-f4586ec93f50 h1:J0A2JsYlb0He1lTGDy+6KX3s/87uklk/pLv9FKv9yp8=
 gitlab.com/elixxir/primitives v0.0.0-20200915190719-f4586ec93f50/go.mod h1:kNp47yPqja2lHSiS4DddTvFpB/4D9dB2YKnw5c+LJCE=
+gitlab.com/elixxir/primitives v0.0.0-20200916172343-37503735c7a1 h1:51FDjTwXKVadID7xRxQxMKequpEjoKAIxaMpAn/YCP0=
+gitlab.com/elixxir/primitives v0.0.0-20200916172343-37503735c7a1/go.mod h1:pJx2DZk9s8vVMnLN7x0hIPngDjbNSdOP6kk3RLlRxHg=
 gitlab.com/xx_network/comms v0.0.0-20200805174823-841427dd5023/go.mod h1:owEcxTRl7gsoM8c3RQ5KAm5GstxrJp5tn+6JfQ4z5Hw=
+gitlab.com/xx_network/comms v0.0.0-20200806235452-3a82720833ba h1:7nozLSNBX0CfP53DDiDNLJx9obhYGfGf5na0/c9rMso=
+gitlab.com/xx_network/comms v0.0.0-20200806235452-3a82720833ba/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY=
+gitlab.com/xx_network/comms v0.0.0-20200812204124-8dc2a2a1b9ca/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY=
+gitlab.com/xx_network/comms v0.0.0-20200818182121-732dd75b1947 h1:g0k4nP0o/6qkh09F9d/Fy7Ys93fkyZU+kK71JviLdMg=
+gitlab.com/xx_network/comms v0.0.0-20200818182121-732dd75b1947/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY=
+gitlab.com/xx_network/comms v0.0.0-20200825213037-f58fa7c0a641 h1:d48S6FLIUJa1RMm5E20P/kbM8upHmfVgoc9G4+TDjhk=
+gitlab.com/xx_network/comms v0.0.0-20200825213037-f58fa7c0a641/go.mod h1:idLzPGYig57XE7xuU93OlIF9s6NgSJj7OArQvsd5DjY=
+gitlab.com/xx_network/comms v0.0.0-20200909172255-8dd37d862d9e h1:TUHn4Mg1hYHT5mMmCjsh6p+joJK2zwoLgq2x3LC2LUk=
+gitlab.com/xx_network/comms v0.0.0-20200909172255-8dd37d862d9e/go.mod h1:+jEkDQKoK51WLl2ZZuxfAZkz6YFbUQ+oZfH0dt2wIF0=
+gitlab.com/xx_network/comms v0.0.0-20200910173932-bd179f5fee4f h1:ExTCqEoro7VuS1eOs889STiYfvR0m1RMDytwOHGW/+k=
+gitlab.com/xx_network/comms v0.0.0-20200910173932-bd179f5fee4f/go.mod h1:+jEkDQKoK51WLl2ZZuxfAZkz6YFbUQ+oZfH0dt2wIF0=
+gitlab.com/xx_network/comms v0.0.0-20200915154643-d533291041b7 h1:lPx1wpkjNpwLaZ0pyd7/iCcdITjT+eCMmb0HXCVoIkk=
+gitlab.com/xx_network/comms v0.0.0-20200915154643-d533291041b7/go.mod h1:+jEkDQKoK51WLl2ZZuxfAZkz6YFbUQ+oZfH0dt2wIF0=
 gitlab.com/xx_network/comms v0.0.0-20200916172635-6ab807c3c820/go.mod h1:J+GJ6fn71a4xnYVvbcrhtvWSOQIqqhaGcaej5xB3/JY=
 gitlab.com/xx_network/comms v0.0.0-20200924172734-1124191b69ee h1:dPRaW0OxcoBlWALd5H6VUYnL/ALvT7j14kWJNBi0K7A=
 gitlab.com/xx_network/comms v0.0.0-20200924172734-1124191b69ee/go.mod h1:jECvMkoYKZFooCudoZxxaf2bo1DzpWP0gCahXHdlqUM=
-gitlab.com/xx_network/comms v0.0.0-20200925163950-5686bc0f8ab0 h1:oGkaifANbV8PpSWCxvgK9wUU2ZvTY4YKOGhrn21wMgo=
-gitlab.com/xx_network/comms v0.0.0-20200925163950-5686bc0f8ab0/go.mod h1:+jEkDQKoK51WLl2ZZuxfAZkz6YFbUQ+oZfH0dt2wIF0=
-gitlab.com/xx_network/comms v0.0.0-20200925185249-9de661e791fc h1:3GiT4gLxje62bRg+RqD3kVS5VBGLkmPzGEh8xvwUpiA=
-gitlab.com/xx_network/comms v0.0.0-20200925185249-9de661e791fc/go.mod h1:+jEkDQKoK51WLl2ZZuxfAZkz6YFbUQ+oZfH0dt2wIF0=
-gitlab.com/xx_network/comms v0.0.0-20200925191822-08c0799a24a6 h1:CdLCB4MyTWQFUuM5mFEx3RgrkhKOS2LJNkyi7UXatus=
-gitlab.com/xx_network/comms v0.0.0-20200925191822-08c0799a24a6/go.mod h1:+jEkDQKoK51WLl2ZZuxfAZkz6YFbUQ+oZfH0dt2wIF0=
+gitlab.com/xx_network/comms v0.0.0-20200924225518-0c867207b1e6 h1:8rNFHiwKJvcfN89FAmp4RyfjD/rknp4tNm9sI/Nos0g=
+gitlab.com/xx_network/comms v0.0.0-20200924225518-0c867207b1e6/go.mod h1:jECvMkoYKZFooCudoZxxaf2bo1DzpWP0gCahXHdlqUM=
+gitlab.com/xx_network/crypto v0.0.0-20200805231039-4aa0e350ed0a h1:BlfWGPokU6yU69O+PGGsgc5iA/P9gERbHzYUvjoYbgM=
 gitlab.com/xx_network/crypto v0.0.0-20200806202113-978fa1984bbf/go.mod h1:i0df/q6dDCBiscgD51fMoS2U2TBrm6LcyN822JmB5Tw=
+gitlab.com/xx_network/crypto v0.0.0-20200806235322-ede3c15881ce h1:gypNBUl2guESEv4MDgH+miwYqR4jPoWM8dLt2Zs5gIs=
+gitlab.com/xx_network/crypto v0.0.0-20200806235322-ede3c15881ce/go.mod h1:i0df/q6dDCBiscgD51fMoS2U2TBrm6LcyN822JmB5Tw=
 gitlab.com/xx_network/crypto v0.0.0-20200812183430-c77a5281c686 h1:XP7U93c2gk08fs5RkNwtnQ+C+/tAT0AYuPC4xy8GF1A=
 gitlab.com/xx_network/crypto v0.0.0-20200812183430-c77a5281c686/go.mod h1:i0df/q6dDCBiscgD51fMoS2U2TBrm6LcyN822JmB5Tw=
 gitlab.com/xx_network/primitives v0.0.0-20200803231956-9b192c57ea7c/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA=
@@ -212,14 +375,24 @@ gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da h1:CCVslUwNC
 gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug=
 gitlab.com/xx_network/primitives v0.0.0-20200812183720-516a65a4a9b2 h1:Jvv2fLk+2ULDCXiVTPI8Jlg2fBrmq2NSA+dlsN5t2Pk=
 gitlab.com/xx_network/primitives v0.0.0-20200812183720-516a65a4a9b2/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug=
+gitlab.com/xx_network/primitives v0.0.0-20200915203029-799fbff7fc3b h1:OFWO+M+LiGVtMnkxsHlJfXZSGBqaJoXfjK5AnZRJB0w=
+gitlab.com/xx_network/primitives v0.0.0-20200915203029-799fbff7fc3b/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug=
+gitlab.com/xx_network/primitives v0.0.0-20200915204206-eb0287ed0031 h1:QU+UGZPdQXUsKtOfR7hLxjg3/+MI1d+NqXgREQxzOe4=
+gitlab.com/xx_network/primitives v0.0.0-20200915204206-eb0287ed0031/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA=
 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=
+go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
+go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=
 go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
 go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
 go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
 golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
+golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw=
 golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
@@ -232,27 +405,58 @@ golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPh
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a h1:vclmkQCjlDX5OydZ9wv8rBCcS0QyQY66Mpf/7BZbInM=
 golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
+golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=
+golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
+golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
+golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
+golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
+golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
+golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
+golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
+golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
 golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
 golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
+golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -260,26 +464,57 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7
 golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo=
 golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20 h1:4X356008q5SA3YXu8PiRap39KFmy4Lf6sGlceJKZQsU=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6 h1:DvY3Zkh7KabQE/kfzMvYvKirSiguP9Q/veMtkYyf0o8=
+golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200828194041-157a740278f4 h1:kCCpuwSAoYJPkNc6x0xT9yTtV4oKtARo4RGBQWOfg9E=
+golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200917073148-efd3b9a0ff20/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200918174421-af09f7315aff h1:1CPUrky56AcgSpxz/KfgzQWzfG09u5YOL8MvPYBlrL8=
-golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d h1:L/IKR6COd7ubZrs2oTnTi73IhgqJ71c9s80WsQnh0Es=
+golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
 golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
+golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
 golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
 golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
+golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
+golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
+golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
+google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=
+google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
+google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
+google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
 google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
+google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=
+google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
 google.golang.org/genproto v0.0.0-20200514193133-8feb7f20f2a2/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=
 google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
 google.golang.org/genproto v0.0.0-20200709005830-7a2ca40e9dc3 h1:JwLN1jVnmIsfE4HkDVe2AblFAbo0Z+4cjteDSOnv6oE=
@@ -303,9 +538,12 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4=
 gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
+gopkg.in/ini.v1 v1.61.0 h1:LBCdW4FmFYL4s/vDZD1RQYX7oAR6IjujCYgMdbHBR10=
+gopkg.in/ini.v1 v1.61.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
 gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
 gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -317,4 +555,8 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
+honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
+rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
diff --git a/interfaces/message/id.go b/interfaces/message/id.go
deleted file mode 100644
index 7498c0ab52d4fae5c201839e2b9d6f8e07549aa9..0000000000000000000000000000000000000000
--- a/interfaces/message/id.go
+++ /dev/null
@@ -1,35 +0,0 @@
-package message
-
-import (
-	"encoding/binary"
-	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/crypto/hash"
-	"gitlab.com/xx_network/primitives/id"
-)
-
-const messageIDLen = 32
-
-type ID [messageIDLen]byte
-
-func NewID(sender, receiver *id.ID, connectionSalt []byte,
-	internalMessageID uint64) ID {
-	h, err := hash.NewCMixHash()
-	if err != nil {
-		jww.FATAL.Panicf("Failed to get hash for message ID creation")
-	}
-
-	h.Write(sender.Bytes())
-	h.Write(receiver.Bytes())
-
-	intMidBytes := make([]byte, 8)
-	binary.BigEndian.PutUint64(intMidBytes, internalMessageID)
-
-	h.Write(intMidBytes)
-	h.Write(connectionSalt)
-
-	midBytes := h.Sum(nil)
-
-	mid := ID{}
-	copy(mid[:], midBytes)
-	return mid
-}
diff --git a/interfaces/message/receiveMessage.go b/interfaces/message/receiveMessage.go
index 4dbe3b4a7380a64580998f27f5a16d571153cc77..d562e0528b738cc219ccf270932fdf9a993716f6 100644
--- a/interfaces/message/receiveMessage.go
+++ b/interfaces/message/receiveMessage.go
@@ -11,5 +11,4 @@ type Receive struct {
 	Sender      *id.ID
 	Timestamp   time.Time
 	Encryption  EncryptionType
-	Id          ID
 }
diff --git a/storage/e2e/context.go b/storage/e2e/context.go
index c4ef997ecba363657703b1d8368f89bc03ca16df..800c32519ed61498b43e90a42be4d02e18823f07 100644
--- a/storage/e2e/context.go
+++ b/storage/e2e/context.go
@@ -3,6 +3,7 @@ package e2e
 import (
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/primitives/id"
 )
 
 type context struct {
@@ -11,4 +12,6 @@ type context struct {
 	grp *cyclic.Group
 
 	rng *fastRNG.StreamGenerator
+
+	myID *id.ID
 }
diff --git a/storage/e2e/key.go b/storage/e2e/key.go
index be2f6bcba670a8aeca51b3a9e872de16dfe45cdb..6e046afd24eb8192ca21bfbd05014e1da0ddc39a 100644
--- a/storage/e2e/key.go
+++ b/storage/e2e/key.go
@@ -90,5 +90,6 @@ func (k *Key) denoteUse() {
 
 // Generates the key and returns it
 func (k *Key) generateKey() e2eCrypto.Key {
-	return e2eCrypto.DeriveKey(k.session.baseKey, k.keyNum)
+	return e2eCrypto.DeriveKey(k.session.baseKey, k.keyNum,
+		k.session.relationshipFingerprint)
 }
diff --git a/storage/e2e/key_test.go b/storage/e2e/key_test.go
index 00fc39822d65eae78fed0479a19b17f828a66426..272e1932f5b6a9737d9e26c256a63586643bc8d2 100644
--- a/storage/e2e/key_test.go
+++ b/storage/e2e/key_test.go
@@ -202,8 +202,8 @@ func getSession(t *testing.T) *Session {
 	}
 
 	return &Session{
-		manager: &Manager{
-			ctx: ctx,
+		relationship: &relationship{
+			manager: &Manager{ctx: ctx},
 		},
 		baseKey:  baseKey,
 		keyState: keyState,
diff --git a/storage/e2e/manager.go b/storage/e2e/manager.go
index 71287c4922a7f1cd5e96f02a3d5f1161722e27f8..2770b7d12bf07d30727aa50d34305de70961c10a 100644
--- a/storage/e2e/manager.go
+++ b/storage/e2e/manager.go
@@ -9,7 +9,9 @@ package e2e
 import (
 	"fmt"
 	"github.com/pkg/errors"
+	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/interfaces/params"
+	"gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
@@ -17,6 +19,8 @@ import (
 )
 
 const managerPrefix = "Manager{partner:%s}"
+const originMyPrivKeyKey = "originMyPrivKey"
+const originPartnerPubKey = "originPartnerPubKey"
 
 type Manager struct {
 	ctx *context
@@ -24,69 +28,86 @@ type Manager struct {
 
 	partner *id.ID
 
-	receive *sessionBuff
-	send    *sessionBuff
+	originMyPrivKey     *cyclic.Int
+	originPartnerPubKey *cyclic.Int
+
+	receive *relationship
+	send    *relationship
 }
 
-// newManager creates the manager and its first send and receive sessions.
+// newManager creates the relationship and its first Send and Receive sessions.
 func newManager(ctx *context, kv *versioned.KV, partnerID *id.ID, myPrivKey,
 	partnerPubKey *cyclic.Int, sendParams, receiveParams SessionParams) *Manager {
 
 	kv = kv.Prefix(fmt.Sprintf(managerPrefix, partnerID))
 
 	m := &Manager{
-		ctx:     ctx,
-		kv:      kv,
-		partner: partnerID,
+		ctx:                 ctx,
+		kv:                  kv,
+		originMyPrivKey:     myPrivKey,
+		originPartnerPubKey: partnerPubKey,
+		partner:             partnerID,
 	}
 
-	m.send = NewSessionBuff(m, "send")
-	m.receive = NewSessionBuff(m, "receive")
-
-	sendSession := newSession(m, myPrivKey, partnerPubKey, nil,
-		sendParams, Send, SessionID{})
-
-	m.send.AddSession(sendSession)
+	if err := utility.StoreCyclicKey(kv, myPrivKey, originMyPrivKeyKey); err != nil {
+		jww.FATAL.Panicf("Failed to store %s: %+v", originMyPrivKeyKey,
+			err)
+	}
 
-	receiveSession := newSession(m, myPrivKey, partnerPubKey, nil,
-		receiveParams, Receive, SessionID{})
+	if err := utility.StoreCyclicKey(kv, partnerPubKey, originPartnerPubKey);
+		err != nil {
+		jww.FATAL.Panicf("Failed to store %s: %+v", originPartnerPubKey,
+			err)
+	}
 
-	m.receive.AddSession(receiveSession)
+	m.send = NewRelationship(m, Send, sendParams)
+	m.receive = NewRelationship(m, Receive, receiveParams)
 
 	return m
 }
 
-// loadManager loads a manager and all buffers and sessions from disk.
+//loads a relationship and all buffers and sessions from disk
 func loadManager(ctx *context, kv *versioned.KV, partnerID *id.ID) (*Manager, error) {
 
 	kv = kv.Prefix(fmt.Sprintf(managerPrefix, partnerID))
 
 	m := &Manager{
 		ctx:     ctx,
-		kv:      kv,
 		partner: partnerID,
+		kv:      kv,
 	}
 
 	var err error
+	m.originMyPrivKey, err = utility.LoadCyclicKey(kv, originMyPrivKeyKey)
+	if err != nil {
+		jww.FATAL.Panicf("Failed to load %s: %+v", originMyPrivKeyKey,
+			err)
+	}
 
-	m.send, err = LoadSessionBuff(m, "send")
+	m.originPartnerPubKey, err = utility.LoadCyclicKey(kv, originPartnerPubKey)
+	if err != nil {
+		jww.FATAL.Panicf("Failed to load %s: %+v", originPartnerPubKey,
+			err)
+	}
+
+	m.send, err = LoadRelationship(m, Send)
 	if err != nil {
 		return nil, errors.WithMessage(err,
-			"Failed to load partner key manager due to failure to "+
-				"load the send session buffer")
+			"Failed to load partner key relationship due to failure to "+
+				"load the Send session buffer")
 	}
 
-	m.receive, err = LoadSessionBuff(m, "receive")
+	m.receive, err = LoadRelationship(m, Receive)
 	if err != nil {
 		return nil, errors.WithMessage(err,
-			"Failed to load partner key manager due to failure to "+
-				"load the receive session buffer")
+			"Failed to load partner key relationship due to failure to "+
+				"load the Receive session buffer")
 	}
 
 	return m, nil
 }
 
-// NewReceiveSession creates a new receive session using the latest private key
+// NewReceiveSession creates a new Receive session using the latest private key
 // this user has sent and the new public key received from the partner. If the
 // session already exists, then it will not be overwritten and the extant
 // session will be returned with the bool set to true denoting a duplicate. This
@@ -102,35 +123,27 @@ func (m *Manager) NewReceiveSession(partnerPubKey *cyclic.Int, params SessionPar
 		return s, true
 	}
 
-	// Create the session but do not save
-	session := newSession(m, source.myPrivKey, partnerPubKey, baseKey, params,
-		Receive, source.GetID())
-
 	// Add the session to the buffer
-	m.receive.AddSession(session)
+	session := m.receive.AddSession(source.myPrivKey, partnerPubKey, baseKey,
+		source.GetID(), params)
 
 	return session, false
 }
 
-// NewSendSession creates a new receive session using the latest public key
+// NewSendSession creates a new Receive session using the latest public key
 // received from the partner and a new private key for the user. Passing in a
 // private key is optional. A private key will be generated if none is passed.
 func (m *Manager) NewSendSession(myPrivKey *cyclic.Int, params SessionParams) *Session {
 	// Find the latest public key from the other party
 	sourceSession := m.receive.getNewestRekeyableSession()
 
-	// Create the session
-	session := newSession(m, myPrivKey, sourceSession.partnerPubKey, nil,
-		params, Send, sourceSession.GetID())
-
-	// Add the session to the send session buffer and return
-	m.send.AddSession(session)
-
-	return session
+	// Add the session to the Send session buffer and return
+	return m.send.AddSession(myPrivKey, sourceSession.partnerPubKey, nil,
+		sourceSession.GetID(), params)
 }
 
-// GetKeyForSending gets the correct session to send with depending on the type
-// of send.
+// GetKeyForSending gets the correct session to Send with depending on the type
+// of Send.
 func (m *Manager) GetKeyForSending(st params.SendType) (*Key, error) {
 	switch st {
 	case params.Standard:
@@ -149,19 +162,19 @@ func (m *Manager) GetPartnerID() *id.ID {
 	return p
 }
 
-// GetSendSession gets the send session of the passed ID. Returns nil if no
+// GetSendSession gets the Send session of the passed ID. Returns nil if no
 // session is found.
 func (m *Manager) GetSendSession(sid SessionID) *Session {
 	return m.send.GetByID(sid)
 }
 
-// GetReceiveSession gets the receive session of the passed ID. Returns nil if
+// GetReceiveSession gets the Receive session of the passed ID. Returns nil if
 // no session is found.
 func (m *Manager) GetReceiveSession(sid SessionID) *Session {
 	return m.receive.GetByID(sid)
 }
 
-// Confirm confirms a send session is known about by the partner.
+// Confirm confirms a Send session is known about by the partner.
 func (m *Manager) Confirm(sid SessionID) error {
 	return m.send.Confirm(sid)
 }
diff --git a/storage/e2e/manager_test.go b/storage/e2e/manager_test.go
index a5bbeb7cad449b0a09053448135e93b158e48fcd..52edccd82e99b0cedbaf97397a5e66cd832f198c 100644
--- a/storage/e2e/manager_test.go
+++ b/storage/e2e/manager_test.go
@@ -20,22 +20,20 @@ func Test_newManager(t *testing.T) {
 	kv := versioned.NewKV(make(ekv.Memstore))
 	partnerID := id.NewIdFromUInt(100, id.User, t)
 	expectedM := &Manager{
-		ctx:     ctx,
-		kv:      kv.Prefix(fmt.Sprintf(managerPrefix, partnerID)),
-		partner: partnerID,
+		ctx:                 ctx,
+		kv:                  kv.Prefix(fmt.Sprintf(managerPrefix, partnerID)),
+		partner:             partnerID,
+		originPartnerPubKey: s.partnerPubKey,
+		originMyPrivKey:     s.myPrivKey,
 	}
-	expectedM.send = NewSessionBuff(expectedM, "send")
-	expectedM.receive = NewSessionBuff(expectedM, "receive")
-	expectedM.send.AddSession(newSession(expectedM, s.myPrivKey,
-		s.partnerPubKey, nil, s.params, Send, SessionID{}))
-	expectedM.receive.AddSession(newSession(expectedM, s.myPrivKey,
-		s.partnerPubKey, nil, s.params, Receive, SessionID{}))
-
-	// Create new manager
+	expectedM.send = NewRelationship(expectedM, Send, GetDefaultSessionParams())
+	expectedM.receive = NewRelationship(expectedM, Receive, GetDefaultSessionParams())
+
+	// Create new relationship
 	m := newManager(ctx, kv, partnerID, s.myPrivKey, s.partnerPubKey, s.params,
 		s.params)
 
-	// Check if the new manager matches the expected
+	// Check if the new relationship matches the expected
 	if !managersEqual(expectedM, m, t) {
 		t.Errorf("newManager() did not produce the expected Manager."+
 			"\n\texpected: %+v\n\treceived: %+v", expectedM, m)
@@ -47,13 +45,13 @@ func TestLoadManager(t *testing.T) {
 	// Set up expected and test values
 	expectedM, kv := newTestManager(t)
 
-	// Attempt to load manager
+	// Attempt to load relationship
 	m, err := loadManager(expectedM.ctx, kv, expectedM.partner)
 	if err != nil {
 		t.Errorf("loadManager() returned an error: %v", err)
 	}
 
-	// Check if the loaded manager matches the expected
+	// Check if the loaded relationship matches the expected
 	if !managersEqual(expectedM, m, t) {
 		t.Errorf("loadManager() did not produce the expected Manager."+
 			"\n\texpected: %+v\n\treceived: %+v", expectedM, m)
@@ -224,7 +222,7 @@ func TestManager_TriggerNegotiations(t *testing.T) {
 	}
 }
 
-// newTestManager returns a new manager for testing.
+// newTestManager returns a new relationship for testing.
 func newTestManager(t *testing.T) (*Manager, *versioned.KV) {
 	prng := rand.New(rand.NewSource(time.Now().UnixNano()))
 	s, ctx := makeTestSession()
@@ -232,7 +230,7 @@ func newTestManager(t *testing.T) (*Manager, *versioned.KV) {
 	partnerID := id.NewIdFromUInts([4]uint64{prng.Uint64(), prng.Uint64(),
 		prng.Uint64(), prng.Uint64()}, id.User, t)
 
-	// Create new manager
+	// Create new relationship
 	m := newManager(ctx, kv, partnerID, s.myPrivKey, s.partnerPubKey, s.params,
 		s.params)
 
@@ -242,31 +240,31 @@ func newTestManager(t *testing.T) (*Manager, *versioned.KV) {
 func managersEqual(expected, received *Manager, t *testing.T) bool {
 	equal := true
 	if !reflect.DeepEqual(expected.ctx, received.ctx) {
-		t.Errorf("Did not receive expected Manager.ctx."+
+		t.Errorf("Did not Receive expected Manager.ctx."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.ctx, received.ctx)
 		equal = false
 	}
 	if !reflect.DeepEqual(expected.kv, received.kv) {
-		t.Errorf("Did not receive expected Manager.kv."+
+		t.Errorf("Did not Receive expected Manager.kv."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.kv, received.kv)
 		equal = false
 	}
 	if !expected.partner.Cmp(received.partner) {
-		t.Errorf("Did not receive expected Manager.partner."+
+		t.Errorf("Did not Receive expected Manager.partner."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.partner, received.partner)
 		equal = false
 	}
-	if !sessionBuffsEqual(expected.receive, received.receive) {
-		t.Errorf("Did not receive expected Manager.receive."+
+	if !relationshipsEqual(expected.receive, received.receive) {
+		t.Errorf("Did not Receive expected Manager.Receive."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.receive, received.receive)
 		equal = false
 	}
-	if !sessionBuffsEqual(expected.send, received.send) {
-		t.Errorf("Did not receive expected Manager.send."+
+	if !relationshipsEqual(expected.send, received.send) {
+		t.Errorf("Did not Receive expected Manager.Send."+
 			"\n\texpected: %+v\n\treceived: %+v",
 			expected.send, received.send)
 		equal = false
diff --git a/storage/e2e/sessionBuff.go b/storage/e2e/relationship.go
similarity index 53%
rename from storage/e2e/sessionBuff.go
rename to storage/e2e/relationship.go
index d8c0e260a1b12afb37d1eb7b26f5d7e9fe83df92..9995a80ad2cbcd072a28cc519a52b499c7430169 100644
--- a/storage/e2e/sessionBuff.go
+++ b/storage/e2e/relationship.go
@@ -8,90 +8,122 @@ package e2e
 
 import (
 	"encoding/json"
-	"fmt"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/crypto/cyclic"
 	"sync"
 	"time"
 )
 
 const maxUnconfirmed uint = 3
-const currentSessionBuffVersion = 0
+const currentRelationshipVersion = 0
+const currentRelationshipFingerprintVersion = 0
+const relationshipKey = "relationship"
+const relationshipFingerprintKey = "relationshipFingerprint"
 
-type sessionBuff struct {
+type relationship struct {
 	manager *Manager
+	t       RelationshipType
 
 	kv *versioned.KV
 
 	sessions    []*Session
 	sessionByID map[SessionID]*Session
 
-	key string
+	fingerprint []byte
 
 	mux     sync.RWMutex
 	sendMux sync.Mutex
 }
 
-func NewSessionBuff(manager *Manager, key string) *sessionBuff {
-	return &sessionBuff{
+func NewRelationship(manager *Manager, t RelationshipType,
+	initialParams SessionParams) *relationship {
+
+	kv := manager.kv.Prefix(t.prefix())
+
+	//build the fingerprint
+	fingerprint := makeRelationshipFingerprint(t, manager.ctx.grp,
+		manager.originMyPrivKey, manager.originPartnerPubKey, manager.ctx.myID,
+		manager.partner)
+
+	if err := storeRelationshipFingerprint(fingerprint, kv); err != nil {
+		jww.FATAL.Panicf("Failed to store relationship fingerpint "+
+			"for new relationship: %+v", err)
+	}
+
+	r := &relationship{
 		manager:     manager,
+		t:           t,
 		sessions:    make([]*Session, 0),
 		sessionByID: make(map[SessionID]*Session),
-		key:         key,
-		kv:          manager.kv,
+		fingerprint: fingerprint,
+		kv:          kv,
 	}
+
+	s := newSession(r, r.t, manager.originMyPrivKey,
+		manager.originPartnerPubKey, nil, SessionID{},
+		r.fingerprint, initialParams)
+
+	r.addSession(s)
+
+	if err := r.save(); err != nil {
+		jww.FATAL.Printf("Failed to save Relationship %s after "+
+			"adding session %s: %s", relationshipKey, s, err)
+	}
+
+	return r
 }
 
-func LoadSessionBuff(manager *Manager, key string) (*sessionBuff, error) {
-	sb := &sessionBuff{
+func LoadRelationship(manager *Manager, t RelationshipType) (*relationship, error) {
+
+	kv := manager.kv.Prefix(t.prefix())
+
+	r := &relationship{
+		t:           t,
 		manager:     manager,
 		sessionByID: make(map[SessionID]*Session),
-		key:         key,
-		kv:          manager.kv,
+		kv:          kv,
 	}
 
-	key = makeSessionBuffKey(key)
-
-	obj, err := manager.kv.Get(key)
+	obj, err := kv.Get(relationshipKey)
 	if err != nil {
 		return nil, err
 	}
 
-	err = sb.unmarshal(obj.Data)
+	err = r.unmarshal(obj.Data)
 
 	if err != nil {
 		return nil, err
 	}
 
-	return sb, nil
+	return r, nil
 }
 
-func (sb *sessionBuff) save() error {
-	key := makeSessionBuffKey(sb.key)
+func (r *relationship) save() error {
 
 	now := time.Now()
 
-	data, err := sb.marshal()
+	data, err := r.marshal()
 	if err != nil {
 		return err
 	}
 
 	obj := versioned.Object{
-		Version:   currentSessionBuffVersion,
+		Version:   currentRelationshipVersion,
 		Timestamp: now,
 		Data:      data,
 	}
 
-	return sb.kv.Set(key, &obj)
+	return r.kv.Set(relationshipKey, &obj)
 }
 
 //ekv functions
-func (sb *sessionBuff) marshal() ([]byte, error) {
-	sessions := make([]SessionID, len(sb.sessions))
+func (r *relationship) marshal() ([]byte, error) {
+	sessions := make([]SessionID, len(r.sessions))
 
 	index := 0
-	for sid := range sb.sessionByID {
+	for sid := range r.sessionByID {
 		sessions[index] = sid
 		index++
 	}
@@ -99,7 +131,7 @@ func (sb *sessionBuff) marshal() ([]byte, error) {
 	return json.Marshal(&sessions)
 }
 
-func (sb *sessionBuff) unmarshal(b []byte) error {
+func (r *relationship) unmarshal(b []byte) error {
 	var sessions []SessionID
 
 	err := json.Unmarshal(b, &sessions)
@@ -108,54 +140,60 @@ func (sb *sessionBuff) unmarshal(b []byte) error {
 		return err
 	}
 
+	//load the fingerprint
+	r.fingerprint = loadRelationshipFingerprint(r.kv)
+
 	//load all the sessions
 	for _, sid := range sessions {
-		sessionKV := sb.kv.Prefix(makeSessionPrefix(sid))
-		session, err := loadSession(sb.manager, sessionKV)
+		sessionKV := r.kv.Prefix(makeSessionPrefix(sid))
+		session, err := loadSession(r, sessionKV, r.fingerprint)
 		if err != nil {
-			jww.FATAL.Panicf("Failed to load session %s for %s: %s",
-				makeSessionPrefix(sid), sb.manager.partner, err.Error())
+			jww.FATAL.Panicf("Failed to load session %s for %s: %+v",
+				makeSessionPrefix(sid), r.manager.partner, err)
 		}
-		sb.addSession(session)
+		r.addSession(session)
 	}
 
 	return nil
 }
 
-func (sb *sessionBuff) AddSession(s *Session) {
-	sb.mux.Lock()
-	defer sb.mux.Unlock()
+func (r *relationship) AddSession(myPrivKey, partnerPubKey, baseKey *cyclic.Int,
+	trigger SessionID, params SessionParams) *Session {
+	r.mux.Lock()
+	defer r.mux.Unlock()
+
+	s := newSession(r, r.t, myPrivKey, partnerPubKey, baseKey, trigger,
+		r.fingerprint, params)
 
-	sb.addSession(s)
-	if err := sb.save(); err != nil {
-		key := makeSessionBuffKey(sb.key)
-		jww.FATAL.Printf("Failed to save Session Buffer %s after "+
-			"adding session %s: %s", key, s, err)
+	r.addSession(s)
+	if err := r.save(); err != nil {
+		jww.FATAL.Printf("Failed to save Relationship %s after "+
+			"adding session %s: %s", relationshipKey, s, err)
 	}
 
-	return
+	return s
 }
 
-func (sb *sessionBuff) addSession(s *Session) {
-	sb.sessions = append([]*Session{s}, sb.sessions...)
-	sb.sessionByID[s.GetID()] = s
+func (r *relationship) addSession(s *Session) {
+	r.sessions = append([]*Session{s}, r.sessions...)
+	r.sessionByID[s.GetID()] = s
 	return
 }
 
-func (sb *sessionBuff) GetNewest() *Session {
-	sb.mux.RLock()
-	defer sb.mux.RUnlock()
-	if len(sb.sessions) == 0 {
+func (r *relationship) GetNewest() *Session {
+	r.mux.RLock()
+	defer r.mux.RUnlock()
+	if len(r.sessions) == 0 {
 		return nil
 	}
-	return sb.sessions[0]
+	return r.sessions[0]
 }
 
 // returns the key  which is most likely to be successful for sending
-func (sb *sessionBuff) getKeyForSending() (*Key, error) {
-	sb.sendMux.Lock()
-	defer sb.sendMux.Unlock()
-	s := sb.getSessionForSending()
+func (r *relationship) getKeyForSending() (*Key, error) {
+	r.sendMux.Lock()
+	defer r.sendMux.Unlock()
+	s := r.getSessionForSending()
 	if s == nil {
 		return nil, errors.New("Failed to find a session for sending")
 	}
@@ -164,8 +202,8 @@ func (sb *sessionBuff) getKeyForSending() (*Key, error) {
 }
 
 // returns the session which is most likely to be successful for sending
-func (sb *sessionBuff) getSessionForSending() *Session {
-	sessions := sb.sessions
+func (r *relationship) getSessionForSending() *Session {
+	sessions := r.sessions
 
 	var confirmedRekey []*Session
 	var unconfirmedActive []*Session
@@ -200,9 +238,9 @@ func (sb *sessionBuff) getSessionForSending() *Session {
 
 // returns a list of session that need rekeys. Nil instances mean a new rekey
 // from scratch
-func (sb *sessionBuff) TriggerNegotiation() []*Session {
+func (r *relationship) TriggerNegotiation() []*Session {
 	//dont need to take the lock due to the use of a copy of the buffer
-	sessions := sb.getInternalBufferShallowCopy()
+	sessions := r.getInternalBufferShallowCopy()
 	var instructions []*Session
 	for _, ses := range sessions {
 		if ses.triggerNegotiation() {
@@ -213,10 +251,10 @@ func (sb *sessionBuff) TriggerNegotiation() []*Session {
 }
 
 // returns a key which should be used for rekeying
-func (sb *sessionBuff) getKeyForRekey() (*Key, error) {
-	sb.sendMux.Lock()
-	defer sb.sendMux.Unlock()
-	s := sb.getNewestRekeyableSession()
+func (r *relationship) getKeyForRekey() (*Key, error) {
+	r.sendMux.Lock()
+	defer r.sendMux.Unlock()
+	s := r.getNewestRekeyableSession()
 	if s == nil {
 		return nil, errors.New("Failed to find a session for rekeying")
 	}
@@ -225,15 +263,14 @@ func (sb *sessionBuff) getKeyForRekey() (*Key, error) {
 }
 
 // returns the newest session which can be used to start a key negotiation
-func (sb *sessionBuff) getNewestRekeyableSession() *Session {
+func (r *relationship) getNewestRekeyableSession() *Session {
 	//dont need to take the lock due to the use of a copy of the buffer
-	sessions := sb.getInternalBufferShallowCopy()
-
+	sessions := r.getInternalBufferShallowCopy()
 	if len(sessions) == 0 {
 		return nil
 	}
-
-	for _, s := range sb.sessions {
+	for _, s := range r.sessions {
+		//fmt.Println(i)
 		// This looks like it might not be thread safe, I think it is because
 		// the failure mode is it skips to a lower key to rekey with, which is
 		// always valid. It isn't clear it can fail though because we are
@@ -245,29 +282,27 @@ func (sb *sessionBuff) getNewestRekeyableSession() *Session {
 	return nil
 }
 
-func (sb *sessionBuff) GetByID(id SessionID) *Session {
-	sb.mux.RLock()
-	defer sb.mux.RUnlock()
-	return sb.sessionByID[id]
+func (r *relationship) GetByID(id SessionID) *Session {
+	r.mux.RLock()
+	defer r.mux.RUnlock()
+	return r.sessionByID[id]
 }
 
 // sets the passed session ID as confirmed. Call "GetSessionRotation" after
 // to get any sessions that are to be deleted and then "DeleteSession" to
 // remove them
-func (sb *sessionBuff) Confirm(id SessionID) error {
-	sb.mux.Lock()
-	defer sb.mux.Unlock()
-	fmt.Printf("sb: %v\n", sb)
-	fmt.Printf("sb.sessionById: %v\n", sb.sessionByID)
+func (r *relationship) Confirm(id SessionID) error {
+	r.mux.Lock()
+	defer r.mux.Unlock()
 
-	s, ok := sb.sessionByID[id]
+	s, ok := r.sessionByID[id]
 	if !ok {
 		return errors.Errorf("Could not confirm session %s, does not exist", id)
 	}
 
 	s.SetNegotiationStatus(Confirmed)
 
-	sb.clean()
+	r.clean()
 
 	return nil
 }
@@ -275,25 +310,25 @@ func (sb *sessionBuff) Confirm(id SessionID) error {
 // adding or removing a session is always done via replacing the entire
 // slice, this allow us to copy the slice under the read lock and do the
 // rest of the work while not taking the lock
-func (sb *sessionBuff) getInternalBufferShallowCopy() []*Session {
-	sb.mux.RLock()
-	defer sb.mux.RUnlock()
-	return sb.sessions
+func (r *relationship) getInternalBufferShallowCopy() []*Session {
+	r.mux.RLock()
+	defer r.mux.RUnlock()
+	return r.sessions
 }
 
-func (sb *sessionBuff) clean() {
+func (r *relationship) clean() {
 
 	numConfirmed := uint(0)
 
 	var newSessions []*Session
 	editsMade := false
 
-	for _, s := range sb.sessions {
+	for _, s := range r.sessions {
 		if s.IsConfirmed() {
 			numConfirmed++
 			//if the number of newer confirmed is sufficient, delete the confirmed
 			if numConfirmed > maxUnconfirmed {
-				delete(sb.sessionByID, s.GetID())
+				delete(r.sessionByID, s.GetID())
 				s.Delete()
 				editsMade = true
 				continue
@@ -304,16 +339,12 @@ func (sb *sessionBuff) clean() {
 
 	//only do the update and save if changes occured
 	if editsMade {
-		sb.sessions = newSessions
+		r.sessions = newSessions
 
-		if err := sb.save(); err != nil {
-			key := makeSessionBuffKey(sb.key)
+		if err := r.save(); err != nil {
 			jww.FATAL.Printf("Failed to save Session Buffer %s after "+
-				"clean: %s", key, err)
+				"clean: %s", r.kv.GetFullKey(relationshipKey), err)
 		}
 	}
 }
 
-func makeSessionBuffKey(key string) string {
-	return "sessionBuffer" + key
-}
diff --git a/storage/e2e/relationshipFingerprint.go b/storage/e2e/relationshipFingerprint.go
new file mode 100644
index 0000000000000000000000000000000000000000..19f01a1d9e801729e10cb598ffcc6f648769fa55
--- /dev/null
+++ b/storage/e2e/relationshipFingerprint.go
@@ -0,0 +1,49 @@
+package e2e
+
+import (
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/e2e"
+	"gitlab.com/xx_network/primitives/id"
+	"time"
+)
+
+func makeRelationshipFingerprint(t RelationshipType, grp *cyclic.Group,
+	myPrivKey, partnerPubKey *cyclic.Int, me, partner *id.ID) []byte {
+
+	myPubKey := grp.ExpG(myPrivKey, grp.NewIntFromUInt(1))
+
+	switch t {
+	case Send:
+		return e2e.MakeRelationshipFingerprint(myPubKey, partnerPubKey,
+			me, partner)
+	case Receive:
+		return e2e.MakeRelationshipFingerprint(myPubKey, partnerPubKey,
+			partner, me)
+	default:
+		jww.FATAL.Panicf("Cannot built relationship fingerprint for "+
+			"'%s'", t)
+	}
+	return nil
+}
+
+func storeRelationshipFingerprint(fp []byte, kv *versioned.KV) error {
+	now := time.Now()
+	obj := versioned.Object{
+		Version:   currentRelationshipFingerprintVersion,
+		Timestamp: now,
+		Data:      fp,
+	}
+
+	return kv.Set(relationshipFingerprintKey, &obj)
+}
+
+func loadRelationshipFingerprint(kv *versioned.KV) []byte {
+	obj, err := kv.Get(relationshipFingerprintKey)
+	if err != nil {
+		jww.FATAL.Panicf("Failed to load relationshipFingerprint at %s: "+
+			"%s", kv.GetFullKey(relationshipFingerprintKey), err)
+	}
+	return obj.Data
+}
diff --git a/storage/e2e/relationshipType.go b/storage/e2e/relationshipType.go
new file mode 100644
index 0000000000000000000000000000000000000000..a0542720fa371e63c4282c0a9cd6c843cf73f835
--- /dev/null
+++ b/storage/e2e/relationshipType.go
@@ -0,0 +1,36 @@
+package e2e
+
+import (
+	"fmt"
+	jww "github.com/spf13/jwalterweatherman"
+)
+
+type RelationshipType uint
+
+const (
+	Send RelationshipType = iota
+	Receive
+)
+
+func (rt RelationshipType) String() string {
+	switch rt {
+	case Send:
+		return "Send"
+	case Receive:
+		return "Receive"
+	default:
+		return fmt.Sprintf("Unknown relationship type: %d", rt)
+	}
+}
+
+func (rt RelationshipType) prefix() string {
+	switch rt {
+	case Send:
+		return "Send"
+	case Receive:
+		return "Receive"
+	default:
+		jww.FATAL.Panicf("No prefix for relationship type: %s", rt)
+	}
+	return ""
+}
diff --git a/storage/e2e/sessionBuff_test.go b/storage/e2e/relationship_test.go
similarity index 50%
rename from storage/e2e/sessionBuff_test.go
rename to storage/e2e/relationship_test.go
index 8d724f659a678077c0c343074f46afeccfccf0f5..1972772f778452a9c7750840afcabc60974b0e69 100644
--- a/storage/e2e/sessionBuff_test.go
+++ b/storage/e2e/relationship_test.go
@@ -1,6 +1,7 @@
 package e2e
 
 import (
+	"bytes"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/ekv"
 	"gitlab.com/xx_network/primitives/id"
@@ -9,14 +10,9 @@ import (
 )
 
 // Subtest: unmarshal/marshal with one session in the buff
-func TestSessionBuff_MarshalUnmarshal(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
-
-	g := mgr.ctx.grp
-	session := newSession(mgr, g.NewInt(2), g.NewInt(3), g.NewInt(4), GetDefaultSessionParams(),
-		Receive, SessionID{})
-	sb.AddSession(session)
+func TestRelationship_MarshalUnmarshal(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 
 	// Serialization should include session slice only
 	serialized, err := sb.marshal()
@@ -24,78 +20,84 @@ func TestSessionBuff_MarshalUnmarshal(t *testing.T) {
 		t.Fatal(err)
 	}
 
-	sb2 := NewSessionBuff(mgr, "test")
+	sb2 := &relationship{
+		manager:     mgr,
+		t:           0,
+		kv:          sb.kv,
+		sessions:    make([]*Session, 0),
+		sessionByID: make(map[SessionID]*Session),
+	}
+
 	err = sb2.unmarshal(serialized)
 	if err != nil {
 		t.Fatal(err)
 	}
 
 	// compare sb2 sesh list and map
-	if !sessionBuffsEqual(sb, sb2) {
+	if !relationshipsEqual(sb, sb2) {
 		t.Error("session buffs not equal")
 	}
 }
 
-// Shows that LoadSessionBuff returns an equivalent session buff to the one that was saved
-func TestLoadSessionBuff(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+// Shows that Relationship returns an equivalent session buff to the one that was saved
+func TestLoadRelationship(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 
-	g := mgr.ctx.grp
-	session := newSession(mgr, g.NewInt(2), g.NewInt(3), g.NewInt(4), GetDefaultSessionParams(),
-		Receive, SessionID{})
-	sb.AddSession(session)
 	err := sb.save()
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	sb2, err := LoadSessionBuff(mgr, "test")
+	sb2, err := LoadRelationship(mgr, Send)
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if !sessionBuffsEqual(sb, sb2) {
+	if !relationshipsEqual(sb, sb2) {
 		t.Error("session buffers not equal")
 	}
 }
 
-// Shows that NewSessionBuff returns a valid session buff
-func TestNewSessionBuff(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+// Shows that Relationship returns a valid session buff
+func TestNewRelationshipBuff(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 	if mgr != sb.manager {
 		t.Error("managers should be identical")
 	}
-	if sb.sessionByID == nil || len(sb.sessionByID) != 0 {
-		t.Error("session map should not be nil, and should be empty")
+	if sb.sessionByID == nil || len(sb.sessionByID) != 1 {
+		t.Error("session map should not be nil, and should have one " +
+			"element")
 	}
-	if sb.sessions == nil || len(sb.sessions) != 0 {
-		t.Error("session list should not be nil, and should be empty")
+	if sb.sessions == nil || len(sb.sessions) != 1 {
+		t.Error("session list should not be nil, and should have one " +
+			"element")
 	}
 }
 
-// Shows that AddSession adds one session to the buff
-func TestSessionBuff_AddSession(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
-	if len(sb.sessions) != 0 {
-		t.Error("starting session slice length should be 0")
+// Shows that AddSession adds one session to the relationship
+func TestRelationship_AddSession(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
+	if len(sb.sessions) != 1 {
+		t.Error("starting session slice length should be 1")
 	}
-	if len(sb.sessionByID) != 0 {
-		t.Error("starting session map length should be 0")
+	if len(sb.sessionByID) != 1 {
+		t.Error("starting session map length should be 1")
 	}
 	session, _ := makeTestSession()
-	// Note: AddSession doesn't change the session manager or set anything else up
+	// Note: AddSession doesn't change the session relationship or set anything else up
 	// to match the session to the session buffer. To work properly, the session
-	// should have been created using the same manager (which is not the case in
+	// should have been created using the same relationship (which is not the case in
 	// this test.)
-	sb.AddSession(session)
-	if len(sb.sessions) != 1 {
-		t.Error("ending session slice length should be 1")
+	sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
+		session.partnerSource, session.params)
+	if len(sb.sessions) != 2 {
+		t.Error("ending session slice length should be 2")
 	}
-	if len(sb.sessionByID) != 1 {
-		t.Error("ending session map length should be 1")
+	if len(sb.sessionByID) != 2 {
+		t.Error("ending session map length should be 2")
 	}
 	if session.GetID() != sb.sessions[0].GetID() {
 		t.Error("session added should have same ID")
@@ -103,23 +105,26 @@ func TestSessionBuff_AddSession(t *testing.T) {
 }
 
 // GetNewest should get the session that was most recently added to the buff
-func TestSessionBuff_GetNewest(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+func TestRelationship_GetNewest(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 	// The newest session should be nil upon session buffer creation
 	nilSession := sb.GetNewest()
-	if nilSession != nil {
-		t.Error("should have gotten a nil session from a buffer with no sessions")
+	if nilSession == nil {
+		t.Error("should not have gotten a nil session from a buffer " +
+			"with one session")
 	}
 
 	session, _ := makeTestSession()
-	sb.AddSession(session)
+	sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
+		session.partnerSource, session.params)
 	if session.GetID() != sb.GetNewest().GetID() {
 		t.Error("session added should have same ID")
 	}
 
 	session2, _ := makeTestSession()
-	sb.AddSession(session2)
+	sb.AddSession(session2.myPrivKey, session2.partnerPubKey, nil,
+		session2.partnerSource, session2.params)
 	if session2.GetID() != sb.GetNewest().GetID() {
 		t.Error("session added should have same ID")
 	}
@@ -127,32 +132,33 @@ func TestSessionBuff_GetNewest(t *testing.T) {
 }
 
 // Shows that Confirm confirms the specified session in the buff
-func TestSessionBuff_Confirm(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+func TestRelationship_Confirm(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 	session, _ := makeTestSession()
-	session.negotiationStatus = Sent
-	adaptToBuff(session, sb, t)
-	sb.AddSession(session)
 
-	if session.IsConfirmed() {
+	sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
+		session.partnerSource, session.params)
+	sb.sessions[1].negotiationStatus = Sent
+
+	if sb.sessions[1].IsConfirmed() {
 		t.Error("session should not be confirmed before confirmation")
 	}
 
-	err := sb.Confirm(session.GetID())
+	err := sb.Confirm(sb.sessions[1].GetID())
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	if !session.IsConfirmed() {
+	if !sb.sessions[1].IsConfirmed() {
 		t.Error("session should be confirmed after confirmation")
 	}
 }
 
 // Shows that the session buff returns an error when the session doesn't exist
-func TestSessionBuff_Confirm_Err(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+func TestRelationship_Confirm_Err(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 	session, _ := makeTestSession()
 
 	err := sb.Confirm(session.GetID())
@@ -162,11 +168,12 @@ func TestSessionBuff_Confirm_Err(t *testing.T) {
 }
 
 // Shows that a session can get got by ID from the buff
-func TestSessionBuff_GetByID(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+func TestRelationship_GetByID(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 	session, _ := makeTestSession()
-	sb.AddSession(session)
+	session = sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
+		session.partnerSource, session.params)
 	session2 := sb.GetByID(session.GetID())
 	if !reflect.DeepEqual(session, session2) {
 		t.Error("gotten session should be the same")
@@ -175,9 +182,9 @@ func TestSessionBuff_GetByID(t *testing.T) {
 
 // Shows that GetNewestRekeyableSession acts as expected:
 // returning sessions that are confirmed and past ttl
-func TestSessionBuff_GetNewestRekeyableSession(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+func TestRelationship_GetNewestRekeyableSession(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
 
 	// no available rekeyable sessions: nil
 	session2 := sb.getNewestRekeyableSession()
@@ -187,32 +194,53 @@ func TestSessionBuff_GetNewestRekeyableSession(t *testing.T) {
 
 	// add a rekeyable session: that session
 	session, _ := makeTestSession()
-	sb.AddSession(session)
+	sb.AddSession(session.myPrivKey, session.partnerPubKey, session.baseKey,
+		session.partnerSource, session.params)
+	sb.sessions[0].negotiationStatus = Confirmed
 	session3 := sb.getNewestRekeyableSession()
-	if session3.GetID() != session.GetID() {
+
+	if session3 == nil {
+		t.Error("no session returned")
+	} else if session3.GetID() != sb.sessions[0].GetID() {
 		t.Error("didn't get the expected session")
 	}
 
 	// add another rekeyable session: that session
+	// show the newest session is selected
 	additionalSession, _ := makeTestSession()
-	sb.AddSession(additionalSession)
+	sb.AddSession(additionalSession.myPrivKey, additionalSession.partnerPubKey,
+		additionalSession.partnerPubKey, additionalSession.partnerSource,
+		additionalSession.params)
+
+	sb.sessions[0].negotiationStatus = Confirmed
+
 	session4 := sb.getNewestRekeyableSession()
-	if session4.GetID() != additionalSession.GetID() {
+	if session4 == nil {
+		t.Error("no session returned")
+	} else if session4.GetID() != sb.sessions[0].GetID() {
 		t.Error("didn't get the expected session")
 	}
 
+
 	// make the very newest session unrekeyable: the previous session
-	additionalSession.negotiationStatus = Unconfirmed
+	//sb.sessions[1].negotiationStatus = Confirmed
+	sb.sessions[0].negotiationStatus = Unconfirmed
+
 	session5 := sb.getNewestRekeyableSession()
-	if session5.GetID() != session.GetID() {
+	if session5 == nil {
+		t.Error("no session returned")
+	} else if session5.GetID() != sb.sessions[1].GetID() {
 		t.Error("didn't get the expected session")
 	}
 }
 
 // Shows that GetSessionForSending follows the hierarchy of sessions correctly
-func TestSessionBuff_GetSessionForSending(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+func TestRelationship_GetSessionForSending(t *testing.T) {
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
+
+	sb.sessions = make([]*Session, 0)
+	sb.sessionByID = make(map[SessionID]*Session)
 
 	none := sb.getSessionForSending()
 	if none != nil {
@@ -221,51 +249,64 @@ func TestSessionBuff_GetSessionForSending(t *testing.T) {
 
 	// First case: unconfirmed rekey
 	unconfirmedRekey, _ := makeTestSession()
-	unconfirmedRekey.negotiationStatus = Unconfirmed
-	unconfirmedRekey.keyState.numAvailable = 600
-	t.Log(unconfirmedRekey.Status())
-	sb.AddSession(unconfirmedRekey)
+
+	sb.AddSession(unconfirmedRekey.myPrivKey, unconfirmedRekey.partnerPubKey,
+		unconfirmedRekey.partnerPubKey, unconfirmedRekey.partnerSource,
+		unconfirmedRekey.params)
+	sb.sessions[0].negotiationStatus = Unconfirmed
+	sb.sessions[0].keyState.numAvailable = 600
 	sending := sb.getSessionForSending()
-	if sending.GetID() != unconfirmedRekey.GetID() {
+	if sending.GetID() != sb.sessions[0].GetID() {
 		t.Error("got an unexpected session")
 	}
 
 	// Second case: unconfirmed active
 	unconfirmedActive, _ := makeTestSession()
-	unconfirmedActive.negotiationStatus = Unconfirmed
-	unconfirmedActive.keyState.numAvailable = 2000
-	t.Log(unconfirmedActive.Status())
-	sb.AddSession(unconfirmedActive)
+
+	sb.AddSession(unconfirmedActive.myPrivKey, unconfirmedActive.partnerPubKey,
+		unconfirmedActive.partnerPubKey, unconfirmedActive.partnerSource,
+		unconfirmedActive.params)
+	sb.sessions[0].negotiationStatus = Unconfirmed
+	sb.sessions[0].keyState.numAvailable = 2000
 	sending = sb.getSessionForSending()
-	if sending.GetID() != unconfirmedActive.GetID() {
+	if sending.GetID() != sb.sessions[0].GetID() {
 		t.Error("got an unexpected session")
 	}
 
 	// Third case: confirmed rekey
 	confirmedRekey, _ := makeTestSession()
-	confirmedRekey.keyState.numAvailable = 600
-	t.Log(confirmedRekey.Status())
-	sb.AddSession(confirmedRekey)
+
+	sb.AddSession(confirmedRekey.myPrivKey, confirmedRekey.partnerPubKey,
+		confirmedRekey.partnerPubKey, confirmedRekey.partnerSource,
+		confirmedRekey.params)
+	sb.sessions[0].negotiationStatus = Confirmed
+	sb.sessions[0].keyState.numAvailable = 600
 	sending = sb.getSessionForSending()
-	if sending.GetID() != confirmedRekey.GetID() {
+	if sending.GetID() != sb.sessions[0].GetID() {
 		t.Error("got an unexpected session")
 	}
 
 	// Fourth case: confirmed active
 	confirmedActive, _ := makeTestSession()
-	confirmedActive.keyState.numAvailable = 2000
-	t.Log(confirmedActive.Status())
-	sb.AddSession(confirmedActive)
+	sb.AddSession(confirmedActive.myPrivKey, confirmedActive.partnerPubKey,
+		confirmedActive.partnerPubKey, confirmedActive.partnerSource,
+		confirmedActive.params)
+
+	sb.sessions[0].negotiationStatus = Confirmed
+	sb.sessions[0].keyState.numAvailable = 2000
 	sending = sb.getSessionForSending()
-	if sending.GetID() != confirmedActive.GetID() {
+	if sending.GetID() != sb.sessions[0].GetID() {
 		t.Error("got an unexpected session")
 	}
 }
 
 // Shows that GetKeyForRekey returns a key if there's an appropriate session for rekeying
 func TestSessionBuff_GetKeyForRekey(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
+
+	sb.sessions = make([]*Session, 0)
+	sb.sessionByID = make(map[SessionID]*Session)
 
 	// no available rekeyable sessions: error
 	key, err := sb.getKeyForRekey()
@@ -277,7 +318,10 @@ func TestSessionBuff_GetKeyForRekey(t *testing.T) {
 	}
 
 	session, _ := makeTestSession()
-	sb.AddSession(session)
+	sb.AddSession(session.myPrivKey, session.partnerPubKey,
+		session.partnerPubKey, session.partnerSource,
+		session.params)
+	sb.sessions[0].negotiationStatus = Confirmed
 	key, err = sb.getKeyForRekey()
 	if err != nil {
 		t.Error(err)
@@ -289,8 +333,11 @@ func TestSessionBuff_GetKeyForRekey(t *testing.T) {
 
 // Shows that GetKeyForSending returns a key if there's an appropriate session for sending
 func TestSessionBuff_GetKeyForSending(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
+
+	sb.sessions = make([]*Session, 0)
+	sb.sessionByID = make(map[SessionID]*Session)
 
 	// no available rekeyable sessions: error
 	key, err := sb.getKeyForSending()
@@ -302,7 +349,9 @@ func TestSessionBuff_GetKeyForSending(t *testing.T) {
 	}
 
 	session, _ := makeTestSession()
-	sb.AddSession(session)
+	sb.AddSession(session.myPrivKey, session.partnerPubKey,
+		session.partnerPubKey, session.partnerSource,
+		session.params)
 	key, err = sb.getKeyForSending()
 	if err != nil {
 		t.Error(err)
@@ -314,35 +363,49 @@ func TestSessionBuff_GetKeyForSending(t *testing.T) {
 
 // Shows that TriggerNegotiation sets up for negotiation correctly
 func TestSessionBuff_TriggerNegotiation(t *testing.T) {
-	mgr := makeTestSessionBuffManager(t)
-	sb := NewSessionBuff(mgr, "test")
+	mgr := makeTestRelationshipManager(t)
+	sb := NewRelationship(mgr, Send, GetDefaultSessionParams())
+	sb.sessions = make([]*Session, 0)
+	sb.sessionByID = make(map[SessionID]*Session)
+
 	session, _ := makeTestSession()
-	sb.AddSession(session)
+	session = sb.AddSession(session.myPrivKey, session.partnerPubKey,
+		session.partnerPubKey, session.partnerSource,
+		session.params)
+	session.negotiationStatus = Confirmed
 	// The added session isn't ready for rekey so it's not returned here
 	negotiations := sb.TriggerNegotiation()
 	if len(negotiations) != 0 {
-		t.Error("should have had zero negotiations")
+		t.Errorf("should have had zero negotiations: %+v", negotiations)
 	}
 	session2, _ := makeTestSession()
 	// Make only a few keys available to trigger the ttl
+	session2 = sb.AddSession(session2.myPrivKey, session2.partnerPubKey,
+		session2.partnerPubKey, session2.partnerSource,
+		session2.params)
 	session2.keyState.numAvailable = 4
-	sb.AddSession(session2)
+	session2.negotiationStatus = Confirmed
 	negotiations = sb.TriggerNegotiation()
 	if len(negotiations) != 1 {
 		t.Fatal("should have had one negotiation")
 	}
 	if negotiations[0].GetID() != session2.GetID() {
-		t.Error("negotiated sessions should include the rekeyable session")
+		t.Error("negotiated sessions should include the rekeyable " +
+			"session")
 	}
 	if session2.negotiationStatus != NewSessionTriggered {
-		t.Error("Trigger negotiations should have set status to triggered")
+		t.Errorf("Trigger negotiations should have set status to "+
+			"triggered: %s", session2.negotiationStatus)
 	}
 
 	// Unconfirmed sessions should also be included in the list
 	// as the client should attempt to confirm them
 	session3, _ := makeTestSession()
+
+	session3 = sb.AddSession(session3.myPrivKey, session3.partnerPubKey,
+		session3.partnerPubKey, session3.partnerSource,
+		session3.params)
 	session3.negotiationStatus = Unconfirmed
-	sb.AddSession(session3)
 
 	// Set session 2 status back to Confirmed to show that more than one session can be returned
 	session2.negotiationStatus = Confirmed
@@ -376,32 +439,25 @@ func TestSessionBuff_TriggerNegotiation(t *testing.T) {
 	}
 }
 
-func makeTestSessionBuff(t *testing.T) *sessionBuff {
-	sb := &sessionBuff{
-		manager:     makeTestSessionBuffManager(t),
-		sessions:    make([]*Session, 0),
-		sessionByID: make(map[SessionID]*Session),
-		key:         "test",
-	}
-	sb.kv = sb.manager.kv
-	return sb
-}
-
-func makeTestSessionBuffManager(t *testing.T) *Manager {
+func makeTestRelationshipManager(t *testing.T) *Manager {
 	fps := newFingerprints()
+	g := getGroup()
 	return &Manager{
 		ctx: &context{
-			fa:  &fps,
-			grp: getGroup(),
+			fa:   &fps,
+			grp:  g,
+			myID: &id.ID{},
 		},
-		kv:      versioned.NewKV(make(ekv.Memstore)),
-		partner: id.NewIdFromUInt(8, id.User, t),
+		kv:                  versioned.NewKV(make(ekv.Memstore)),
+		partner:             id.NewIdFromUInt(8, id.User, t),
+		originMyPrivKey:     g.NewInt(2),
+		originPartnerPubKey: g.NewInt(3),
 	}
 }
 
 // Revises a session to fit a sessionbuff and saves it to the sessionbuff's kv store
-func adaptToBuff(session *Session, buff *sessionBuff, t *testing.T) {
-	session.manager = buff.manager
+func adaptToBuff(session *Session, buff *relationship, t *testing.T) {
+	session.relationship = buff
 	session.keyState.kv = buff.manager.kv
 	err := session.keyState.save()
 	if err != nil {
@@ -414,16 +470,17 @@ func adaptToBuff(session *Session, buff *sessionBuff, t *testing.T) {
 }
 
 // Compare certain fields of two session buffs for equality
-func sessionBuffsEqual(buff *sessionBuff, buff2 *sessionBuff) bool {
-	if buff.key != buff2.key {
-		return false
-	}
+func relationshipsEqual(buff *relationship, buff2 *relationship) bool {
 	if len(buff.sessionByID) != len(buff2.sessionByID) {
 		return false
 	}
 	if len(buff.sessions) != len(buff2.sessions) {
 		return false
 	}
+
+	if !bytes.Equal(buff.fingerprint, buff2.fingerprint) {
+		return false
+	}
 	// Make sure all sessions are present
 	for k := range buff.sessionByID {
 		_, ok := buff2.sessionByID[k]
@@ -441,3 +498,4 @@ func sessionBuffsEqual(buff *sessionBuff, buff2 *sessionBuff) bool {
 	}
 	return true
 }
+
diff --git a/storage/e2e/session.go b/storage/e2e/session.go
index 42f7f342c2f5df396c05830741d08fd606940756..351d93ac5be2d8aa349018beff26805057689ccf 100644
--- a/storage/e2e/session.go
+++ b/storage/e2e/session.go
@@ -28,15 +28,15 @@ const sessionPrefix = "session{ID:%s}"
 const sessionKey = "session"
 
 type Session struct {
-	//pointer to manager
-	manager *Manager
+	//pointer to relationship
+	relationship *relationship
 	//prefixed kv
 	kv *versioned.KV
 	//params
 	params SessionParams
 
 	//type
-	t SessionType
+	t RelationshipType
 
 	// Underlying key
 	baseKey *cyclic.Int
@@ -45,9 +45,11 @@ type Session struct {
 	// Partner Public Key
 	partnerPubKey *cyclic.Int
 	// ID of the session which teh partner public key comes from for this
-	// sessions creation.  Shares a partner public key if a send session,
-	// shares a myPrivateKey if a receive session
+	// sessions creation.  Shares a partner public key if a Send session,
+	// shares a myPrivateKey if a Receive session
 	partnerSource SessionID
+	//fingerprint of relationship
+	relationshipFingerprint []byte
 
 	//denotes if the other party has confirmed this key
 	negotiationStatus Negotiation
@@ -90,9 +92,9 @@ type SessionDisk struct {
 
 /*CONSTRUCTORS*/
 //Generator which creates all keys and structures
-func newSession(manager *Manager, myPrivKey, partnerPubKey,
-	baseKey *cyclic.Int, params SessionParams, t SessionType,
-	trigger SessionID) *Session {
+func newSession(ship *relationship, t RelationshipType, myPrivKey, partnerPubKey,
+	baseKey *cyclic.Int, trigger SessionID, relationshipFingerprint []byte,
+	params SessionParams) *Session {
 
 	confirmation := Unconfirmed
 	if t == Receive {
@@ -100,38 +102,40 @@ func newSession(manager *Manager, myPrivKey, partnerPubKey,
 	}
 
 	session := &Session{
-		params:            params,
-		manager:           manager,
-		t:                 t,
-		myPrivKey:         myPrivKey,
-		partnerPubKey:     partnerPubKey,
-		baseKey:           baseKey,
-		negotiationStatus: confirmation,
-		partnerSource:     trigger,
+		params:                  params,
+		relationship:            ship,
+		t:                       t,
+		myPrivKey:               myPrivKey,
+		partnerPubKey:           partnerPubKey,
+		baseKey:                 baseKey,
+		relationshipFingerprint: relationshipFingerprint,
+		negotiationStatus:       confirmation,
+		partnerSource:           trigger,
 	}
 
-	session.kv = session.generate(manager.kv)
+	session.kv = session.generate(ship.kv)
 
 	err := session.save()
 	if err != nil {
 		jww.FATAL.Printf("Failed to make new session for Partner %s: %s",
-			manager.partner, err)
+			ship.manager.partner, err)
 	}
 
 	return session
 }
 
 // Load session and state vector from kv and populate runtime fields
-func loadSession(manager *Manager, kv *versioned.KV) (*Session, error) {
+func loadSession(ship *relationship, kv *versioned.KV,
+	relationshipFingerprint []byte) (*Session, error) {
 
 	session := Session{
-		manager: manager,
-		kv:      kv,
+		relationship: ship,
+		kv:           kv,
 	}
 
 	obj, err := kv.Get(sessionKey)
 	if err != nil {
-		return nil, err
+		return nil, errors.WithMessagef(err, "Failed to load %s", kv.GetFullKey(sessionKey))
 	}
 
 	err = session.unmarshal(obj.Data)
@@ -141,8 +145,9 @@ func loadSession(manager *Manager, kv *versioned.KV) (*Session, error) {
 
 	if session.t == Receive {
 		// register key fingerprints
-		manager.ctx.fa.add(session.getUnusedKeys())
+		ship.manager.ctx.fa.add(session.getUnusedKeys())
 	}
+	session.relationshipFingerprint = relationshipFingerprint
 
 	return &session, nil
 }
@@ -172,7 +177,7 @@ func (s *Session) Delete() {
 	s.mux.Lock()
 	defer s.mux.Unlock()
 
-	s.manager.ctx.fa.remove(s.getUnusedKeys())
+	s.relationship.manager.ctx.fa.remove(s.getUnusedKeys())
 
 	stateVectorErr := s.keyState.Delete()
 	sessionErr := s.kv.Delete(sessionKey)
@@ -241,8 +246,8 @@ func (s *Session) GetID() SessionID {
 
 // returns the ID of the partner for this session
 func (s *Session) GetPartner() *id.ID {
-	if s.manager != nil {
-		return s.manager.partner
+	if s.relationship != nil {
+		return s.relationship.manager.partner
 	} else {
 		return nil
 	}
@@ -284,10 +289,10 @@ func (s *Session) unmarshal(b []byte) error {
 		return err
 	}
 
-	grp := s.manager.ctx.grp
+	grp := s.relationship.manager.ctx.grp
 
 	s.params = sd.Params
-	s.t = SessionType(sd.Type)
+	s.t = RelationshipType(sd.Type)
 	s.baseKey = grp.NewIntFromBytes(sd.BaseKey)
 	s.myPrivKey = grp.NewIntFromBytes(sd.MyPrivKey)
 	s.partnerPubKey = grp.NewIntFromBytes(sd.PartnerPubKey)
@@ -328,8 +333,12 @@ func (s *Session) PopReKey() (*Key, error) {
 	return newKey(s, keyNum), nil
 }
 
+func (s *Session) GetRelationshipFingerprint() []byte {
+	return s.relationshipFingerprint
+}
+
 // returns the state of the session, which denotes if the Session is active,
-// functional but in need of a rekey, empty of send key, or empty of rekeys
+// functional but in need of a rekey, empty of Send key, or empty of rekeys
 func (s *Session) Status() Status {
 	// copy the num available so it stays consistent as this function does its
 	// checks
@@ -480,6 +489,7 @@ func (s *Session) NegotiationStatus() Negotiation {
 // checks if the session has been confirmed
 func (s *Session) IsConfirmed() bool {
 	c := s.NegotiationStatus()
+	//fmt.Println(c)
 	return c >= Confirmed
 }
 
@@ -501,11 +511,11 @@ func (s *Session) useKey(keynum uint32) {
 // generates keys from the base data stored in the session object.
 // myPrivKey will be generated if not present
 func (s *Session) generate(kv *versioned.KV) *versioned.KV {
-	grp := s.manager.ctx.grp
+	grp := s.relationship.manager.ctx.grp
 
 	//generate private key if it is not present
 	if s.myPrivKey == nil {
-		stream := s.manager.ctx.rng.GetStream()
+		stream := s.relationship.manager.ctx.rng.GetStream()
 		s.myPrivKey = dh.GeneratePrivateKey(dh.DefaultPrivateKeyLength, grp,
 			stream)
 		stream.Close()
@@ -542,7 +552,7 @@ func (s *Session) generate(kv *versioned.KV) *versioned.KV {
 	//register keys for reception if this is a reception session
 	if s.t == Receive {
 		//register keys
-		s.manager.ctx.fa.add(s.getUnusedKeys())
+		s.relationship.manager.ctx.fa.add(s.getUnusedKeys())
 	}
 
 	return kv
diff --git a/storage/e2e/sessionType.go b/storage/e2e/sessionType.go
deleted file mode 100644
index 44081daa95c387420094a289c8cfdc13eac8a504..0000000000000000000000000000000000000000
--- a/storage/e2e/sessionType.go
+++ /dev/null
@@ -1,19 +0,0 @@
-package e2e
-
-type SessionType uint8
-
-const (
-	Send SessionType = iota
-	Receive
-)
-
-func (st SessionType) String() string {
-	switch st {
-	case Send:
-		return "Send"
-	case Receive:
-		return "Receive"
-	default:
-		return "Unknown"
-	}
-}
diff --git a/storage/e2e/sessionType_test.go b/storage/e2e/sessionType_test.go
deleted file mode 100644
index 404ca7a76f3edf71d142f9db815b5f42d4d0d7c9..0000000000000000000000000000000000000000
--- a/storage/e2e/sessionType_test.go
+++ /dev/null
@@ -1,28 +0,0 @@
-package e2e
-
-import (
-	"math"
-	"testing"
-)
-
-//tests the stringers for all possible sessions types are correct
-func TestSessionType_String(t *testing.T) {
-	for i := 0; i <= math.MaxUint8; i++ {
-		st := SessionType(i)
-		if st.String() != correctString(i) {
-			t.Errorf("Session Name for %v incorrect. Expected: %s, "+
-				"Received: %s", i, correctString(i), st.String())
-		}
-	}
-}
-
-func correctString(i int) string {
-	switch i {
-	case 0:
-		return "Send"
-	case 1:
-		return "Receive"
-	default:
-		return "Unknown"
-	}
-}
diff --git a/storage/e2e/session_test.go b/storage/e2e/session_test.go
index 5b2bb5b95fab81ef538cb5924b9f48bd7fbfffda..d4c130649c6ef2d2c197d0a6fde18f92a70d1d7c 100644
--- a/storage/e2e/session_test.go
+++ b/storage/e2e/session_test.go
@@ -32,8 +32,8 @@ func TestSession_generate_noPrivateKeyReceive(t *testing.T) {
 	s := &Session{
 		partnerPubKey: partnerPubKey,
 		params:        GetDefaultSessionParams(),
-		manager: &Manager{
-			ctx: ctx,
+		relationship: &relationship{
+			manager: &Manager{ctx: ctx},
 		},
 		t: Receive,
 	}
@@ -93,8 +93,8 @@ func TestSession_generate_PrivateKeySend(t *testing.T) {
 		myPrivKey:     myPrivKey,
 		partnerPubKey: partnerPubKey,
 		params:        GetDefaultSessionParams(),
-		manager: &Manager{
-			ctx: ctx,
+		relationship: &relationship{
+			manager: &Manager{ctx: ctx},
 		},
 		t: Send,
 	}
@@ -138,7 +138,9 @@ func TestNewSession(t *testing.T) {
 	// Make a test session to easily populate all the fields
 	sessionA, _ := makeTestSession()
 	// Make a new session with the variables we got from makeTestSession
-	sessionB := newSession(sessionA.manager, sessionA.myPrivKey, sessionA.partnerPubKey, sessionA.baseKey, sessionA.params, sessionA.t, sessionA.GetID())
+	sessionB := newSession(sessionA.relationship, sessionA.t, sessionA.myPrivKey,
+		sessionA.partnerPubKey, sessionA.baseKey, sessionA.GetID(), []byte(""),
+		sessionA.params)
 
 	err := cmpSerializedFields(sessionA, sessionB)
 	if err != nil {
@@ -148,8 +150,8 @@ func TestNewSession(t *testing.T) {
 	if sessionB.keyState == nil {
 		t.Error("newSession should populate keyState")
 	}
-	if sessionB.manager == nil {
-		t.Error("newSession should populate manager")
+	if sessionB.relationship == nil {
+		t.Error("newSession should populate relationship")
 	}
 	if sessionB.ttl == 0 {
 		t.Error("newSession should populate ttl")
@@ -165,7 +167,7 @@ func TestSession_Load(t *testing.T) {
 		t.Fatal(err)
 	}
 	// Load another, hopefully identical session from the storage
-	sessionB, err := loadSession(sessionA.manager, sessionA.kv)
+	sessionB, err := loadSession(sessionA.relationship, sessionA.kv, []byte(""))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -180,8 +182,8 @@ func TestSession_Load(t *testing.T) {
 		t.Error(err)
 	}
 	// For everything else, just make sure it's populated
-	if sessionB.manager == nil {
-		t.Error("load should populate manager")
+	if sessionB.relationship == nil {
+		t.Error("load should populate relationship")
 	}
 	if sessionB.ttl == 0 {
 		t.Error("load should populate ttl")
@@ -222,8 +224,10 @@ func TestSession_Serialization(t *testing.T) {
 	}
 
 	sDeserialized := &Session{
-		manager: &Manager{ctx: ctx},
-		kv:      s.kv,
+		relationship: &relationship{
+			manager: &Manager{ctx: ctx},
+		},
+		kv: s.kv,
 	}
 	err = sDeserialized.unmarshal(sSerialized)
 	if err != nil {
@@ -573,7 +577,7 @@ func TestSession_TriggerNegotiation(t *testing.T) {
 func TestSession_String(t *testing.T) {
 	s, _ := makeTestSession()
 	t.Log(s.String())
-	s.manager.partner = id.NewIdFromUInt(80, id.User, t)
+	s.relationship.manager.partner = id.NewIdFromUInt(80, id.User, t)
 	t.Log(s.String())
 }
 
@@ -599,8 +603,9 @@ func makeTestSession() (*Session, *context) {
 	//create context objects for general use
 	fps := newFingerprints()
 	ctx := &context{
-		fa:  &fps,
-		grp: grp,
+		fa:   &fps,
+		grp:  grp,
+		myID: &id.ID{},
 	}
 
 	kv := versioned.NewKV(make(ekv.Memstore))
@@ -610,9 +615,12 @@ func makeTestSession() (*Session, *context) {
 		myPrivKey:     myPrivKey,
 		partnerPubKey: partnerPubKey,
 		params:        GetDefaultSessionParams(),
-		manager: &Manager{
-			ctx: ctx,
-			kv:  kv,
+		relationship: &relationship{
+			manager: &Manager{
+				ctx: ctx,
+				kv:  kv,
+			},
+			kv: kv,
 		},
 		kv:                kv,
 		t:                 Receive,
diff --git a/storage/e2e/store.go b/storage/e2e/store.go
index d1e19b5430292959bf8cfb11df515013b1f0aa93..03f1cf27721fd0e34073201221ea293f12f03aca 100644
--- a/storage/e2e/store.go
+++ b/storage/e2e/store.go
@@ -46,7 +46,7 @@ type Store struct {
 }
 
 func NewStore(grp *cyclic.Group, kv *versioned.KV, privKey *cyclic.Int,
-	rng *fastRNG.StreamGenerator) (*Store, error) {
+	myID *id.ID, rng *fastRNG.StreamGenerator) (*Store, error) {
 	// Generate public key
 	pubKey := diffieHellman.GeneratePublicKey(privKey, grp)
 
@@ -68,9 +68,10 @@ func NewStore(grp *cyclic.Group, kv *versioned.KV, privKey *cyclic.Int,
 		kv: kv,
 
 		context: &context{
-			fa:  &fingerprints,
-			grp: grp,
-			rng: rng,
+			fa:   &fingerprints,
+			grp:  grp,
+			rng:  rng,
+			myID: myID,
 		},
 	}
 
@@ -92,7 +93,7 @@ func NewStore(grp *cyclic.Group, kv *versioned.KV, privKey *cyclic.Int,
 	return s, s.save()
 }
 
-func LoadStore(kv *versioned.KV, rng *fastRNG.StreamGenerator) (*Store, error) {
+func LoadStore(kv *versioned.KV, myID *id.ID, rng *fastRNG.StreamGenerator) (*Store, error) {
 	fingerprints := newFingerprints()
 	kv = kv.Prefix(packagePrefix)
 
@@ -104,8 +105,9 @@ func LoadStore(kv *versioned.KV, rng *fastRNG.StreamGenerator) (*Store, error) {
 		kv: kv,
 
 		context: &context{
-			fa:  &fingerprints,
-			rng: rng,
+			fa:   &fingerprints,
+			rng:  rng,
+			myID: myID,
 		},
 	}
 
@@ -163,7 +165,7 @@ func (s *Store) GetPartner(partnerID *id.ID) (*Manager, error) {
 	m, ok := s.managers[*partnerID]
 
 	if !ok {
-		return nil, errors.New("Could not find manager for partner")
+		return nil, errors.New("Could not find relationship for partner")
 	}
 
 	return m, nil
@@ -218,11 +220,11 @@ func (s *Store) unmarshal(b []byte) error {
 	}
 
 	for _, partnerID := range contacts {
-		// Load the manager. The manager handles adding the fingerprints via the
+		// Load the relationship. The relationship handles adding the fingerprints via the
 		// context object
 		manager, err := loadManager(s.context, s.kv, &partnerID)
 		if err != nil {
-			jww.FATAL.Panicf("Failed to load manager for partner %s: %s",
+			jww.FATAL.Panicf("Failed to load relationship for partner %s: %s",
 				&partnerID, err.Error())
 		}
 
diff --git a/storage/e2e/store_test.go b/storage/e2e/store_test.go
index 9a2a498cc8f1f258d84ded3858a70daaa54ac556..ce8c962a75efce22c9a79beff0dec5a0097713a3 100644
--- a/storage/e2e/store_test.go
+++ b/storage/e2e/store_test.go
@@ -31,9 +31,10 @@ func TestNewStore(t *testing.T) {
 		kv:           kv.Prefix(packagePrefix),
 		fingerprints: &fingerprints,
 		context: &context{
-			fa:  &fingerprints,
-			grp: grp,
-			rng: rng,
+			fa:   &fingerprints,
+			grp:  grp,
+			rng:  rng,
+			myID: &id.ID{},
 		},
 	}
 	expectedData, err := expectedStore.marshal()
@@ -41,7 +42,7 @@ func TestNewStore(t *testing.T) {
 		t.Fatalf("marshal() produced an error: %v", err)
 	}
 
-	store, err := NewStore(grp, kv, privKey, rng)
+	store, err := NewStore(grp, kv, privKey, &id.ID{}, rng)
 	if err != nil {
 		t.Errorf("NewStore() produced an error: %v", err)
 	}
@@ -66,14 +67,14 @@ func TestNewStore(t *testing.T) {
 func TestLoadStore(t *testing.T) {
 	expectedStore, kv, rng := makeTestStore()
 
-	store, err := LoadStore(kv, rng)
+	store, err := LoadStore(kv, &id.ID{}, rng)
 	if err != nil {
 		t.Errorf("LoadStore() produced an error: %v", err)
 	}
 
 	if !reflect.DeepEqual(expectedStore, store) {
 		t.Errorf("LoadStore() returned incorrect Store."+
-			"\n\texpected: %+v\n\treceived: %+v", expectedStore, store)
+			"\n\texpected: %#v\n\treceived: %#v", expectedStore, store)
 	}
 }
 
@@ -131,7 +132,7 @@ func TestStore_GetPartner_Error(t *testing.T) {
 	}
 
 	if m != nil {
-		t.Errorf("GetPartner() did not return a nil manager."+
+		t.Errorf("GetPartner() did not return a nil relationship."+
 			"\n\texpected: %v\n\treceived: %v", nil, m)
 	}
 }
@@ -278,7 +279,7 @@ func makeTestStore() (*Store, *versioned.KV, *fastRNG.StreamGenerator) {
 	privKey := grp.NewInt(57)
 	kv := versioned.NewKV(make(ekv.Memstore))
 	rng := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG)
-	s, err := NewStore(grp, kv, privKey, rng)
+	s, err := NewStore(grp, kv, privKey, &id.ID{}, rng)
 	if err != nil {
 		panic("NewStore() produced an error: " + err.Error())
 	}
diff --git a/storage/partition/part.go b/storage/partition/part.go
index 7a6052d96ee8f2cbd66d89642f0217e5ee5745da..c38ca4597dd9e48b4fdc76cbbb4eb35019c463e9 100644
--- a/storage/partition/part.go
+++ b/storage/partition/part.go
@@ -42,6 +42,6 @@ func makeMultiPartMessagePartKey(part uint8) string {
 }
 
 //func multiPartMessagePartPrefix(kv *versioned.KV, id uint64) *versioned.KV {
-//	return kv.Prefix(keyMultiPartMessagePartPrefix).
-//		Prefix(strconv.FormatUint(id, 32))
+//	return kv.prefix(keyMultiPartMessagePartPrefix).
+//		prefix(strconv.FormatUint(id, 32))
 //}
diff --git a/storage/session.go b/storage/session.go
index 862792df2b905c29143584d7c2c1db2d3b183efe..c9d07731c120194d33f945d1213c5db24a9264f5 100644
--- a/storage/session.go
+++ b/storage/session.go
@@ -90,13 +90,14 @@ func New(baseDir, password string, u userInterface.User, cmixGrp,
 	if err != nil {
 		return nil, errors.WithMessage(err, "Failed to create user")
 	}
+	uid := s.user.GetCryptographicIdentity().GetUserID()
 
 	s.cmix, err = cmix.NewStore(cmixGrp, s.kv, u.CmixDhPrivateKey)
 	if err != nil {
 		return nil, errors.WithMessage(err, "Failed to create cmix store")
 	}
 
-	s.e2e, err = e2e.NewStore(e2eGrp, s.kv, u.E2eDhPrivateKey, rng)
+	s.e2e, err = e2e.NewStore(e2eGrp, s.kv, u.E2eDhPrivateKey, uid, rng)
 	if err != nil {
 		return nil, errors.WithMessage(err, "Failed to create e2e store")
 	}
@@ -144,7 +145,9 @@ func Load(baseDir, password string, rng *fastRNG.StreamGenerator) (*Session, err
 		return nil, errors.WithMessage(err, "Failed to load Session")
 	}
 
-	s.e2e, err = e2e.LoadStore(s.kv, rng)
+	uid := s.user.GetCryptographicIdentity().GetUserID()
+
+	s.e2e, err = e2e.LoadStore(s.kv, uid, rng)
 	if err != nil {
 		return nil, errors.WithMessage(err, "Failed to load Session")
 	}
@@ -251,7 +254,8 @@ func InitTestingSession(i interface{}) *Session {
 	store := make(ekv.Memstore)
 	kv := versioned.NewKV(store)
 	s := &Session{kv: kv}
-	u, err := user.NewUser(kv, id.NewIdFromString("zezima", id.User, i), []byte("salt"), privKey, false)
+	uid := id.NewIdFromString("zezima", id.User, i)
+	u, err := user.NewUser(kv, uid, []byte("salt"), privKey, false)
 	if err != nil {
 		globals.Log.FATAL.Panicf("InitTestingSession failed to create dummy user: %+v", err)
 	}
@@ -280,7 +284,7 @@ func InitTestingSession(i interface{}) *Session {
 	}
 	s.cmix = cmix
 
-	e2eStore, err := e2e.NewStore(cmixGrp, kv, cmixGrp.NewInt(2),
+	e2eStore, err := e2e.NewStore(cmixGrp, kv, cmixGrp.NewInt(2), uid,
 		fastRNG.NewStreamGenerator(7, 3, csprng.NewSystemRNG))
 	if err != nil {
 		globals.Log.FATAL.Panicf("InitTestingSession failed to create dummy cmix session: %+v", err)
diff --git a/storage/versioned/kv.go b/storage/versioned/kv.go
index cb13324783388d4fe6292ed696ed9027e79934cf..1fd48d13e7cbcd198ce74680f2fe6ab7b95cf2e4 100644
--- a/storage/versioned/kv.go
+++ b/storage/versioned/kv.go
@@ -126,3 +126,8 @@ func (v *KV) Prefix(prefix string) *KV {
 	}
 	return &kvPrefix
 }
+
+//Returns the key with all prefixes appended
+func (v *KV) GetFullKey(key string) string {
+	return v.prefix + key
+}