diff --git a/auth/request.go b/auth/request.go
index 75459786839b8fd6730b9bc58bb44cca67cbb7c5..91cda7a3f324bf7f14ae6b8052e3caccf725767c 100644
--- a/auth/request.go
+++ b/auth/request.go
@@ -8,6 +8,7 @@
 package auth
 
 import (
+	e2e2 "gitlab.com/elixxir/client/e2e/ratchet"
 	"io"
 	"strings"
 
@@ -19,7 +20,6 @@ import (
 	"gitlab.com/elixxir/client/interfaces/preimage"
 	"gitlab.com/elixxir/client/storage"
 	"gitlab.com/elixxir/client/storage/auth"
-	"gitlab.com/elixxir/client/storage/e2e"
 	"gitlab.com/elixxir/client/storage/edge"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/crypto/contact"
@@ -35,7 +35,7 @@ func RequestAuth(partner, me contact.Contact, rng io.Reader,
 	storage *storage.Session, net interfaces.NetworkManager) (id.Round, error) {
 	// check that an authenticated channel does not already exist
 	if _, err := storage.E2e().GetPartner(partner.ID); err == nil ||
-		!strings.Contains(err.Error(), e2e.NoPartnerErrorStr) {
+		!strings.Contains(err.Error(), e2e2.NoPartnerErrorStr) {
 		return 0, errors.Errorf("Authenticated channel already " +
 			"established with partner")
 	}
diff --git a/e2e/interface.go b/e2e/interface.go
new file mode 100644
index 0000000000000000000000000000000000000000..2ccf9f6076e0e81d5c5c2563c57bb34dbbba5065
--- /dev/null
+++ b/e2e/interface.go
@@ -0,0 +1,28 @@
+package e2e
+
+import (
+	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/interfaces/message"
+	message2 "gitlab.com/elixxir/client/network/message"
+	"gitlab.com/elixxir/client/stoppable"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/e2e"
+	"gitlab.com/xx_network/primitives/id"
+	"time"
+)
+
+type Handler interface {
+	SendE2E(m message.Send, p params.E2E, stop *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error)
+	SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error)
+	AddPartner(partnerID *id.ID, partnerPubKey,
+		myPrivKey *cyclic.Int, partnerSIDHPubKey *sidh.PublicKey, mySIDHPrivKey *sidh.PrivateKey,
+		sendParams, receiveParams params.E2ESessionParams)
+	GetPartner(partnerID *id.ID) (*Manager, error)
+	DeletePartner(partnerId *id.ID)
+	GetAllPartnerIDs() []*id.ID
+	//aproach 2
+	AddService(tag string, source []byte, processor message2.Processor)
+	RemoveService(tag string, source []byte)
+}
+type Manager interface {
+}
diff --git a/storage/e2e/context.go b/e2e/ratchet/context.go
similarity index 97%
rename from storage/e2e/context.go
rename to e2e/ratchet/context.go
index beb7211ed6f8b1caca614a46bb76a03c76651c84..27279e4fd5c23f92f764cdac7e29bce2b66356ac 100644
--- a/storage/e2e/context.go
+++ b/e2e/ratchet/context.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package ratchet
 
 import (
 	"gitlab.com/elixxir/crypto/cyclic"
diff --git a/storage/e2e/fingerprintAccess.go b/e2e/ratchet/fingerprintAccess.go
similarity index 81%
rename from storage/e2e/fingerprintAccess.go
rename to e2e/ratchet/fingerprintAccess.go
index 82e130ed4da604ffe310f1f81362d08ab1c01130..aefb0fd56b4539de14022b3b45d1ee691d96fad3 100644
--- a/storage/e2e/fingerprintAccess.go
+++ b/e2e/ratchet/fingerprintAccess.go
@@ -5,11 +5,15 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package ratchet
+
+import (
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+)
 
 type fingerprintAccess interface {
 	// Receives a list of fingerprints to add. Overrides on collision.
-	add([]*Key)
+	add([]*session2.Cypher)
 	// Receives a list of fingerprints to delete. Ignores any not available Keys
-	remove([]*Key)
+	remove([]*session2.Cypher)
 }
diff --git a/storage/e2e/manager.go b/e2e/ratchet/partner/manager.go
similarity index 77%
rename from storage/e2e/manager.go
rename to e2e/ratchet/partner/manager.go
index 610c1b75f2e2c273f745e0824ad60325aae1462d..29f30fd12e6313575901f2342a6d570c39ec9930 100644
--- a/storage/e2e/manager.go
+++ b/e2e/ratchet/partner/manager.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package partner
 
 import (
 	"bytes"
@@ -14,11 +14,14 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/e2e/ratchet"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/interfaces/preimage"
 	"gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/xx_network/primitives/id"
 	"golang.org/x/crypto/blake2b"
 )
@@ -28,9 +31,9 @@ const originMyPrivKeyKey = "originMyPrivKey"
 const originPartnerPubKey = "originPartnerPubKey"
 
 type Manager struct {
-	ctx *context
-	kv  *versioned.KV
+	kv *versioned.KV
 
+	myID    *id.ID
 	partner *id.ID
 
 	originMyPrivKey     *cyclic.Int
@@ -41,30 +44,33 @@ type Manager struct {
 
 	receive *relationship
 	send    *relationship
+
+	grp       *cyclic.Group
+	cyHandler session.CypherHandler
+	rng       *fastRNG.StreamGenerator
 }
 
-// newManager creates the relationship and its first Send and Receive sessions.
-func newManager(ctx *context, kv *versioned.KV, partnerID *id.ID, myPrivKey,
+// NewManager creates the relationship and its first Send and Receive sessions.
+func NewManager(kv *versioned.KV, myID, partnerID *id.ID, myPrivKey,
 	partnerPubKey *cyclic.Int, mySIDHPrivKey *sidh.PrivateKey,
 	partnerSIDHPubKey *sidh.PublicKey, sendParams,
-	receiveParams params.E2ESessionParams) *Manager {
+	receiveParams session.Params, cyHandler session.CypherHandler,
+	grp *cyclic.Group, rng *fastRNG.StreamGenerator) *Manager {
 
-	kv = kv.Prefix(fmt.Sprintf(managerPrefix, partnerID))
+	kv = kv.Prefix(makeManagerPrefix(partnerID))
 
 	m := &Manager{
-		ctx:                     ctx,
 		kv:                      kv,
 		originMyPrivKey:         myPrivKey,
 		originPartnerPubKey:     partnerPubKey,
 		originMySIDHPrivKey:     mySIDHPrivKey,
 		originPartnerSIDHPubKey: partnerSIDHPubKey,
+		myID:                    myID,
 		partner:                 partnerID,
+		cyHandler:               cyHandler,
+		grp:                     grp,
+		rng:                     rng,
 	}
-
-	if ctx.grp == nil {
-		panic("group not set")
-	}
-
 	if err := utility.StoreCyclicKey(kv, myPrivKey, originMyPrivKeyKey); err != nil {
 		jww.FATAL.Panicf("Failed to store %s: %+v", originMyPrivKeyKey,
 			err)
@@ -75,28 +81,34 @@ func newManager(ctx *context, kv *versioned.KV, partnerID *id.ID, myPrivKey,
 			err)
 	}
 
-	m.send = NewRelationship(m, Send, sendParams)
-	m.receive = NewRelationship(m, Receive, receiveParams)
+	m.send = NewRelationship(m.kv, session.Send, myID, partnerID, myPrivKey,
+		partnerPubKey, mySIDHPrivKey, partnerSIDHPubKey, sendParams, cyHandler,
+		grp, rng)
+	m.receive = NewRelationship(m.kv, session.Receive, myID, partnerID,
+		myPrivKey, partnerPubKey, mySIDHPrivKey, partnerSIDHPubKey,
+		receiveParams, cyHandler, grp, rng)
 
 	return m
 }
 
 //loads a relationship and all buffers and sessions from disk
-func loadManager(ctx *context, kv *versioned.KV, partnerID *id.ID) (*Manager, error) {
+func loadManager(kv *versioned.KV, myID, partnerID *id.ID,
+	cyHandler session.CypherHandler, grp *cyclic.Group,
+	rng *fastRNG.StreamGenerator) (*Manager, error) {
 
 	kv = kv.Prefix(fmt.Sprintf(managerPrefix, partnerID))
 
 	m := &Manager{
-		ctx:     ctx,
-		partner: partnerID,
-		kv:      kv,
-	}
-
-	if ctx.grp == nil {
-		panic("group not set")
+		kv:        kv,
+		myID:      myID,
+		partner:   partnerID,
+		cyHandler: cyHandler,
+		grp:       grp,
+		rng:       rng,
 	}
 
 	var err error
+
 	m.originMyPrivKey, err = utility.LoadCyclicKey(kv, originMyPrivKeyKey)
 	if err != nil {
 		jww.FATAL.Panicf("Failed to load %s: %+v", originMyPrivKeyKey,
@@ -109,14 +121,16 @@ func loadManager(ctx *context, kv *versioned.KV, partnerID *id.ID) (*Manager, er
 			err)
 	}
 
-	m.send, err = LoadRelationship(m, Send)
+	m.send, err = LoadRelationship(m.kv, session.Send, myID, partnerID,
+		cyHandler, grp, rng)
 	if err != nil {
 		return nil, errors.WithMessage(err,
 			"Failed to load partner key relationship due to failure to "+
 				"load the Send session buffer")
 	}
 
-	m.receive, err = LoadRelationship(m, Receive)
+	m.receive, err = LoadRelationship(m.kv, session.Receive, myID, partnerID,
+		cyHandler, grp, rng))
 	if err != nil {
 		return nil, errors.WithMessage(err,
 			"Failed to load partner key relationship due to failure to "+
@@ -151,13 +165,13 @@ func clearManager(m *Manager, kv *versioned.KV) error {
 // session will be returned with the bool set to true denoting a duplicate. This
 // allows for support of duplicate key exchange triggering.
 func (m *Manager) NewReceiveSession(partnerPubKey *cyclic.Int,
-	partnerSIDHPubKey *sidh.PublicKey, e2eParams params.E2ESessionParams,
-	source *Session) (*Session, bool) {
+	partnerSIDHPubKey *sidh.PublicKey, e2eParams session.Params,
+	source *session2.Session) (*session2.Session, bool) {
 
 	// Check if the session already exists
-	baseKey := GenerateE2ESessionBaseKey(source.myPrivKey, partnerPubKey,
+	baseKey := session2.GenerateE2ESessionBaseKey(source.myPrivKey, partnerPubKey,
 		m.ctx.grp, source.mySIDHPrivKey, partnerSIDHPubKey)
-	sessionID := getSessionIDFromBaseKey(baseKey)
+	sessionID := session.getSessionIDFromBaseKey(baseKey)
 
 	if s := m.receive.GetByID(sessionID); s != nil {
 		return s, true
@@ -166,7 +180,7 @@ func (m *Manager) NewReceiveSession(partnerPubKey *cyclic.Int,
 	// Add the session to the buffer
 	session := m.receive.AddSession(source.myPrivKey, partnerPubKey, baseKey,
 		source.mySIDHPrivKey, partnerSIDHPubKey,
-		source.GetID(), Confirmed, e2eParams)
+		source.GetID(), session2.Confirmed, e2eParams)
 
 	return session, false
 }
@@ -176,19 +190,19 @@ func (m *Manager) NewReceiveSession(partnerPubKey *cyclic.Int,
 // private key is optional. A private key will be generated if none is passed.
 func (m *Manager) NewSendSession(myPrivKey *cyclic.Int,
 	mySIDHPrivKey *sidh.PrivateKey,
-	e2eParams params.E2ESessionParams) *Session {
+	e2eParams params.E2ESessionParams) *session2.Session {
 	// Find the latest public key from the other party
 	sourceSession := m.receive.getNewestRekeyableSession()
 
 	// Add the session to the Send session buffer and return
 	return m.send.AddSession(myPrivKey, sourceSession.partnerPubKey, nil,
 		mySIDHPrivKey, sourceSession.partnerSIDHPubKey,
-		sourceSession.GetID(), Sending, e2eParams)
+		sourceSession.GetID(), session2.Sending, e2eParams)
 }
 
 // GetKeyForSending gets the correct session to Send with depending on the type
 // of Send.
-func (m *Manager) GetKeyForSending(st params.SendType) (*Key, error) {
+func (m *Manager) GetKeyForSending(st params.SendType) (*session2.Cypher, error) {
 	switch st {
 	case params.Standard:
 		return m.send.getKeyForSending()
@@ -207,7 +221,7 @@ func (m *Manager) GetPartnerID() *id.ID {
 
 // GetSendSession gets the Send session of the passed ID. Returns nil if no
 // session is found.
-func (m *Manager) GetSendSession(sid SessionID) *Session {
+func (m *Manager) GetSendSession(sid session2.SessionID) *session2.Session {
 	return m.send.GetByID(sid)
 }
 
@@ -219,18 +233,18 @@ func (m *Manager) GetSendRelationshipFingerprint() []byte {
 
 // GetReceiveSession gets the Receive session of the passed ID. Returns nil if
 // no session is found.
-func (m *Manager) GetReceiveSession(sid SessionID) *Session {
+func (m *Manager) GetReceiveSession(sid session2.SessionID) *session2.Session {
 	return m.receive.GetByID(sid)
 }
 
 // Confirm confirms a Send session is known about by the partner.
-func (m *Manager) Confirm(sid SessionID) error {
+func (m *Manager) Confirm(sid session2.SessionID) error {
 	return m.send.Confirm(sid)
 }
 
 // TriggerNegotiations returns a list of key exchange operations if any are
 // necessary.
-func (m *Manager) TriggerNegotiations() []*Session {
+func (m *Manager) TriggerNegotiations() []*session2.Session {
 	return m.send.TriggerNegotiation()
 }
 
@@ -298,3 +312,7 @@ func (m *Manager) GetFileTransferPreimage() []byte {
 func (m *Manager) GetGroupRequestPreimage() []byte {
 	return preimage.Generate(m.GetRelationshipFingerprintBytes(), preimage.GroupRq)
 }
+
+func makeManagerPrefix(pid *id.ID) string {
+	return fmt.Sprintf(managerPrefix, pid)
+}
\ No newline at end of file
diff --git a/storage/e2e/manager_test.go b/e2e/ratchet/partner/manager_test.go
similarity index 94%
rename from storage/e2e/manager_test.go
rename to e2e/ratchet/partner/manager_test.go
index 24c0f9ab85fbca4bd0e3d0166c8ae6a1ab7382cd..a8863497731756c99ca5fcff9e93d4318acad3df 100644
--- a/storage/e2e/manager_test.go
+++ b/e2e/ratchet/partner/manager_test.go
@@ -5,12 +5,14 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package partner
 
 import (
 	"bytes"
 	"encoding/base64"
 	"fmt"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/e2e/ratchet/session"
 	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/ekv"
@@ -25,7 +27,7 @@ import (
 // Tests happy path of newManager.
 func Test_newManager(t *testing.T) {
 	// Set up expected and test values
-	s, ctx := makeTestSession()
+	s, ctx := session.makeTestSession()
 	kv := versioned.NewKV(make(ekv.Memstore))
 	partnerID := id.NewIdFromUInt(100, id.User, t)
 	expectedM := &Manager{
@@ -37,9 +39,9 @@ func Test_newManager(t *testing.T) {
 		originPartnerSIDHPubKey: s.partnerSIDHPubKey,
 		originMySIDHPrivKey:     s.mySIDHPrivKey,
 	}
-	expectedM.send = NewRelationship(expectedM, Send,
+	expectedM.send = NewRelationship(expectedM, session2.Send,
 		params.GetDefaultE2ESessionParams())
-	expectedM.receive = NewRelationship(expectedM, Receive,
+	expectedM.receive = NewRelationship(expectedM, session2.Receive,
 		params.GetDefaultE2ESessionParams())
 
 	// Create new relationship
@@ -101,7 +103,7 @@ func TestManager_ClearManager(t *testing.T) {
 func TestManager_NewReceiveSession(t *testing.T) {
 	// Set up test values
 	m, _ := newTestManager(t)
-	s, _ := makeTestSession()
+	s, _ := session.makeTestSession()
 
 	se, exists := m.NewReceiveSession(s.partnerPubKey, s.partnerSIDHPubKey,
 		s.e2eParams, s)
@@ -136,7 +138,7 @@ func TestManager_NewReceiveSession(t *testing.T) {
 func TestManager_NewSendSession(t *testing.T) {
 	// Set up test values
 	m, _ := newTestManager(t)
-	s, _ := makeTestSession()
+	s, _ := session.makeTestSession()
 
 	se := m.NewSendSession(s.myPrivKey, s.mySIDHPrivKey, s.e2eParams)
 	if !m.partner.Cmp(se.GetPartner()) {
@@ -159,7 +161,7 @@ func TestManager_GetKeyForSending(t *testing.T) {
 	// Set up test values
 	m, _ := newTestManager(t)
 	p := params.GetDefaultE2E()
-	expectedKey := &Key{
+	expectedKey := &session2.Cypher{
 		session: m.send.sessions[0],
 	}
 
@@ -175,7 +177,7 @@ func TestManager_GetKeyForSending(t *testing.T) {
 	}
 
 	p.Type = params.KeyExchange
-	m.send.sessions[0].negotiationStatus = NewSessionTriggered
+	m.send.sessions[0].negotiationStatus = session2.NewSessionTriggered
 	expectedKey.keyNum++
 
 	key, err = m.GetKeyForSending(p.Type)
@@ -248,7 +250,7 @@ func TestManager_GetReceiveSession(t *testing.T) {
 // Tests happy path of Manager.Confirm.
 func TestManager_Confirm(t *testing.T) {
 	m, _ := newTestManager(t)
-	m.send.sessions[0].negotiationStatus = Sent
+	m.send.sessions[0].negotiationStatus = session2.Sent
 	err := m.Confirm(m.send.sessions[0].GetID())
 	if err != nil {
 		t.Errorf("Confirm produced an error: %v", err)
@@ -258,7 +260,7 @@ func TestManager_Confirm(t *testing.T) {
 // Tests happy path of Manager.TriggerNegotiations.
 func TestManager_TriggerNegotiations(t *testing.T) {
 	m, _ := newTestManager(t)
-	m.send.sessions[0].negotiationStatus = Unconfirmed
+	m.send.sessions[0].negotiationStatus = session2.Unconfirmed
 	sessions := m.TriggerNegotiations()
 	if !reflect.DeepEqual(m.send.sessions, sessions) {
 		t.Errorf("TriggerNegotiations() returned incorrect sessions."+
@@ -269,7 +271,7 @@ func TestManager_TriggerNegotiations(t *testing.T) {
 // newTestManager returns a new relationship for testing.
 func newTestManager(t *testing.T) (*Manager, *versioned.KV) {
 	prng := rand.New(rand.NewSource(netTime.Now().UnixNano()))
-	s, ctx := makeTestSession()
+	s, ctx := session.makeTestSession()
 	kv := versioned.NewKV(make(ekv.Memstore))
 	partnerID := id.NewIdFromUInts([4]uint64{prng.Uint64(), prng.Uint64(),
 		prng.Uint64(), prng.Uint64()}, id.User, t)
diff --git a/storage/e2e/relationship.go b/e2e/ratchet/partner/relationship.go
similarity index 67%
rename from storage/e2e/relationship.go
rename to e2e/ratchet/partner/relationship.go
index c545841761492ba43b854620b0b6724b67ee7c90..571f255d1d5d47dae69430f97d7e0f1f67b21a26 100644
--- a/storage/e2e/relationship.go
+++ b/e2e/ratchet/partner/relationship.go
@@ -5,16 +5,18 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package partner
 
 import (
 	"encoding/json"
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
-	"gitlab.com/elixxir/client/interfaces/params"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 	"sync"
 )
@@ -26,29 +28,49 @@ const relationshipKey = "relationship"
 const relationshipFingerprintKey = "relationshipFingerprint"
 
 type relationship struct {
-	manager *Manager
-	t       RelationshipType
+	t session.RelationshipType
 
 	kv *versioned.KV
 
-	sessions    []*Session
-	sessionByID map[SessionID]*Session
+	sessions    []*session.Session
+	sessionByID map[session.SessionID]*session.Session
 
 	fingerprint []byte
 
 	mux     sync.RWMutex
 	sendMux sync.Mutex
+
+	grp       *cyclic.Group
+	myID      *id.ID
+	partnerID *id.ID
+
+	cyHandler session.CypherHandler
+	rng       *fastRNG.StreamGenerator
+
+	serviceHandler ServiceHandler
 }
 
-func NewRelationship(manager *Manager, t RelationshipType,
-	initialParams params.E2ESessionParams) *relationship {
+type ServiceHandler interface {
+	AddService(identifier []byte, tag string, source []byte)
+	DeleteKey(identifier []byte, tag string)
+}
 
-	kv := manager.kv.Prefix(t.prefix())
+// fixme - this is weird becasue it creates the relationsip and the session.
+// Should be refactored to create an empty relationship, with a second call
+// adding the session
+func NewRelationship(kv *versioned.KV, t session.RelationshipType,
+	myID, partnerID *id.ID, myOriginPrivateKey,
+	partnerOriginPublicKey *cyclic.Int, originMySIDHPrivKey *sidh.PrivateKey,
+	originPartnerSIDHPubKey *sidh.PublicKey, initialParams session.Params,
+	cyHandler session.CypherHandler, grp *cyclic.Group,
+	rng *fastRNG.StreamGenerator) *relationship {
+
+	kv = kv.Prefix(t.Prefix())
 
 	//build the fingerprint
-	fingerprint := makeRelationshipFingerprint(t, manager.ctx.grp,
-		manager.originMyPrivKey, manager.originPartnerPubKey, manager.ctx.myID,
-		manager.partner)
+	fingerprint := makeRelationshipFingerprint(t, grp,
+		myOriginPrivateKey, partnerOriginPublicKey, myID,
+		partnerID)
 
 	if err := storeRelationshipFingerprint(fingerprint, kv); err != nil {
 		jww.FATAL.Panicf("Failed to store relationship fingerpint "+
@@ -56,22 +78,24 @@ func NewRelationship(manager *Manager, t RelationshipType,
 	}
 
 	r := &relationship{
-		manager:     manager,
 		t:           t,
-		sessions:    make([]*Session, 0),
-		sessionByID: make(map[SessionID]*Session),
+		sessions:    make([]*session.Session, 0),
+		sessionByID: make(map[session.SessionID]*session.Session),
 		fingerprint: fingerprint,
 		kv:          kv,
+		grp:         grp,
+		cyHandler:   cyHandler,
+		rng:         rng,
 	}
 
 	// set to confirmed because the first session is always confirmed as a
 	// result of the negotiation before creation
-	s := newSession(r, r.t, manager.originMyPrivKey,
-		manager.originPartnerPubKey, nil, manager.originMySIDHPrivKey,
-		manager.originPartnerSIDHPubKey, SessionID{},
-		r.fingerprint, Confirmed, initialParams)
+	s := session.NewSession(r.kv, r.t, partnerID, myOriginPrivateKey,
+		partnerOriginPublicKey, nil, originMySIDHPrivKey,
+		originPartnerSIDHPubKey, session.SessionID{},
+		r.fingerprint, session.Confirmed, initialParams, cyHandler, grp, rng)
 
-	if err := s.save(); err != nil {
+	if err := s.Save(); err != nil {
 		jww.FATAL.Panicf("Failed to Send session after setting to "+
 			"confirmed: %+v", err)
 	}
@@ -86,12 +110,43 @@ func NewRelationship(manager *Manager, t RelationshipType,
 	return r
 }
 
+func LoadRelationship(kv *versioned.KV, t session.RelationshipType, myID,
+	partnerID *id.ID, cyHandler session.CypherHandler, grp *cyclic.Group,
+	rng *fastRNG.StreamGenerator) (*relationship, error) {
+
+	kv = kv.Prefix(t.Prefix())
+
+	r := &relationship{
+		t:           t,
+		sessionByID: make(map[session.SessionID]*session.Session),
+		kv:          kv,
+		myID:        myID,
+		partnerID:   partnerID,
+		cyHandler:   cyHandler,
+		grp:         grp,
+		rng:         rng,
+	}
+
+	obj, err := kv.Get(relationshipKey, currentRelationshipVersion)
+	if err != nil {
+		return nil, err
+	}
+
+	err = r.unmarshal(obj.Data)
+
+	if err != nil {
+		return nil, err
+	}
+
+	return r, nil
+}
+
 // DeleteRelationship removes all relationship and
 // relationship adjacent information from storage
 func DeleteRelationship(manager *Manager) error {
 
 	// Delete the send information
-	sendKv := manager.kv.Prefix(Send.prefix())
+	sendKv := manager.kv.Prefix(session.Send.Prefix())
 	manager.send.Delete()
 	if err := deleteRelationshipFingerprint(sendKv); err != nil {
 		return err
@@ -101,7 +156,7 @@ func DeleteRelationship(manager *Manager) error {
 	}
 
 	// Delete the receive information
-	receiveKv := manager.kv.Prefix(Receive.prefix())
+	receiveKv := manager.kv.Prefix(session.Receive.Prefix())
 	manager.receive.Delete()
 	if err := deleteRelationshipFingerprint(receiveKv); err != nil {
 		return err
@@ -113,31 +168,6 @@ func DeleteRelationship(manager *Manager) error {
 	return nil
 }
 
-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),
-		kv:          kv,
-	}
-
-	obj, err := kv.Get(relationshipKey, currentRelationshipVersion)
-	if err != nil {
-		return nil, err
-	}
-
-	err = r.unmarshal(obj.Data)
-
-	if err != nil {
-		return nil, err
-	}
-
-	return r, nil
-}
-
 func (r *relationship) save() error {
 
 	now := netTime.Now()
@@ -158,7 +188,7 @@ func (r *relationship) save() error {
 
 //ekv functions
 func (r *relationship) marshal() ([]byte, error) {
-	sessions := make([]SessionID, len(r.sessions))
+	sessions := make([]session.SessionID, len(r.sessions))
 
 	index := 0
 	for sid := range r.sessionByID {
@@ -170,11 +200,9 @@ func (r *relationship) marshal() ([]byte, error) {
 }
 
 func (r *relationship) unmarshal(b []byte) error {
-	var sessions []SessionID
+	var sessions []session.SessionID
 
-	err := json.Unmarshal(b, &sessions)
-
-	if err != nil {
+	if err := json.Unmarshal(b, &sessions); err != nil {
 		return err
 	}
 
@@ -183,13 +211,13 @@ func (r *relationship) unmarshal(b []byte) error {
 
 	//load all the sessions
 	for _, sid := range sessions {
-		sessionKV := r.kv.Prefix(makeSessionPrefix(sid))
-		session, err := loadSession(r, sessionKV, r.fingerprint)
+		s, err := session.LoadSession(r.kv, sid, r.fingerprint,
+			r.cyHandler, r.grp, r.rng)
 		if err != nil {
 			jww.FATAL.Panicf("Failed to load session %s for %s: %+v",
-				makeSessionPrefix(sid), r.manager.partner, err)
+				session.MakeSessionPrefix(sid), r.partnerID, err)
 		}
-		r.addSession(session)
+		r.addSession(s)
 	}
 
 	return nil
@@ -202,19 +230,18 @@ func (r *relationship) Delete() {
 		delete(r.sessionByID, s.GetID())
 		s.Delete()
 	}
-
 }
 
 func (r *relationship) AddSession(myPrivKey, partnerPubKey, baseKey *cyclic.Int,
 	mySIDHPrivKey *sidh.PrivateKey, partnerSIDHPubKey *sidh.PublicKey,
-	trigger SessionID, negotiationStatus Negotiation,
-	e2eParams params.E2ESessionParams) *Session {
+	trigger session.SessionID, negotiationStatus session.Negotiation,
+	e2eParams session.Params) *session.Session {
 	r.mux.Lock()
 	defer r.mux.Unlock()
 
-	s := newSession(r, r.t, myPrivKey, partnerPubKey, baseKey,
+	s := session.NewSession(r.kv, r.t, r.partnerID, myPrivKey, partnerPubKey, baseKey,
 		mySIDHPrivKey, partnerSIDHPubKey, trigger,
-		r.fingerprint, negotiationStatus, e2eParams)
+		r.fingerprint, negotiationStatus, e2eParams, r.cyHandler, r.grp, r.rng)
 
 	r.addSession(s)
 	if err := r.save(); err != nil {
@@ -225,13 +252,13 @@ func (r *relationship) AddSession(myPrivKey, partnerPubKey, baseKey *cyclic.Int,
 	return s
 }
 
-func (r *relationship) addSession(s *Session) {
-	r.sessions = append([]*Session{s}, r.sessions...)
+func (r *relationship) addSession(s *session.Session) {
+	r.sessions = append([]*session.Session{s}, r.sessions...)
 	r.sessionByID[s.GetID()] = s
 	return
 }
 
-func (r *relationship) GetNewest() *Session {
+func (r *relationship) GetNewest() *session.Session {
 	r.mux.RLock()
 	defer r.mux.RUnlock()
 	if len(r.sessions) == 0 {
@@ -241,7 +268,7 @@ func (r *relationship) GetNewest() *Session {
 }
 
 // returns the key  which is most likely to be successful for sending
-func (r *relationship) getKeyForSending() (*Key, error) {
+func (r *relationship) getKeyForSending() (*session.Cypher, error) {
 	r.sendMux.Lock()
 	defer r.sendMux.Unlock()
 	s := r.getSessionForSending()
@@ -253,12 +280,12 @@ func (r *relationship) getKeyForSending() (*Key, error) {
 }
 
 // returns the session which is most likely to be successful for sending
-func (r *relationship) getSessionForSending() *Session {
+func (r *relationship) getSessionForSending() *session.Session {
 	sessions := r.sessions
 
-	var confirmedRekey []*Session
-	var unconfirmedActive []*Session
-	var unconfirmedRekey []*Session
+	var confirmedRekey []*session.Session
+	var unconfirmedActive []*session.Session
+	var unconfirmedRekey []*session.Session
 
 	jww.TRACE.Printf("[REKEY] Sessions Available: %d", len(sessions))
 
@@ -267,14 +294,14 @@ func (r *relationship) getSessionForSending() *Session {
 		confirmed := s.IsConfirmed()
 		jww.TRACE.Printf("[REKEY] Session Status/Confirmed: %v, %v",
 			status, confirmed)
-		if status == Active && confirmed {
+		if status == session.Active && confirmed {
 			//always return the first confirmed active, happy path
 			return s
-		} else if status == RekeyNeeded && confirmed {
+		} else if status == session.RekeyNeeded && confirmed {
 			confirmedRekey = append(confirmedRekey, s)
-		} else if status == Active && !confirmed {
+		} else if status == session.Active && !confirmed {
 			unconfirmedActive = append(unconfirmedActive, s)
-		} else if status == RekeyNeeded && !confirmed {
+		} else if status == session.RekeyNeeded && !confirmed {
 			unconfirmedRekey = append(unconfirmedRekey, s)
 		}
 	}
@@ -303,12 +330,12 @@ func (r *relationship) getSessionForSending() *Session {
 
 // returns a list of session that need rekeys. Nil instances mean a new rekey
 // from scratch
-func (r *relationship) TriggerNegotiation() []*Session {
+func (r *relationship) TriggerNegotiation() []*session.Session {
 	//dont need to take the lock due to the use of a copy of the buffer
 	sessions := r.getInternalBufferShallowCopy()
-	var instructions []*Session
+	var instructions []*session.Session
 	for _, ses := range sessions {
-		if ses.triggerNegotiation() {
+		if ses.TriggerNegotiation() {
 			instructions = append(instructions, ses)
 		}
 	}
@@ -316,7 +343,7 @@ func (r *relationship) TriggerNegotiation() []*Session {
 }
 
 // returns a key which should be used for rekeying
-func (r *relationship) getKeyForRekey() (*Key, error) {
+func (r *relationship) getKeyForRekey() (*session.Cypher, error) {
 	r.sendMux.Lock()
 	defer r.sendMux.Unlock()
 	s := r.getNewestRekeyableSession()
@@ -328,14 +355,14 @@ func (r *relationship) getKeyForRekey() (*Key, error) {
 }
 
 // returns the newest session which can be used to start a key negotiation
-func (r *relationship) getNewestRekeyableSession() *Session {
+func (r *relationship) getNewestRekeyableSession() *session.Session {
 	//dont need to take the lock due to the use of a copy of the buffer
 	sessions := r.getInternalBufferShallowCopy()
 	if len(sessions) == 0 {
 		return nil
 	}
 
-	var unconfirmed *Session
+	var unconfirmed *session.Session
 
 	for _, s := range r.sessions {
 		jww.TRACE.Printf("[REKEY] Looking at session %s", s)
@@ -344,7 +371,7 @@ func (r *relationship) getNewestRekeyableSession() *Session {
 		// 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
 		// accessing the data in the same order it would be written (i think)
-		if s.Status() != RekeyEmpty {
+		if s.Status() != session.RekeyEmpty {
 			if s.IsConfirmed() {
 				jww.TRACE.Printf("[REKEY] Selected rekey: %s",
 					s)
@@ -359,7 +386,7 @@ func (r *relationship) getNewestRekeyableSession() *Session {
 	return unconfirmed
 }
 
-func (r *relationship) GetByID(id SessionID) *Session {
+func (r *relationship) GetByID(id session.SessionID) *session.Session {
 	r.mux.RLock()
 	defer r.mux.RUnlock()
 	return r.sessionByID[id]
@@ -368,7 +395,7 @@ func (r *relationship) GetByID(id SessionID) *Session {
 // 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 (r *relationship) Confirm(id SessionID) error {
+func (r *relationship) Confirm(id session.SessionID) error {
 	r.mux.Lock()
 	defer r.mux.Unlock()
 
@@ -377,7 +404,7 @@ func (r *relationship) Confirm(id SessionID) error {
 		return errors.Errorf("Could not confirm session %s, does not exist", id)
 	}
 
-	s.SetNegotiationStatus(Confirmed)
+	s.SetNegotiationStatus(session.Confirmed)
 
 	r.clean()
 
@@ -387,7 +414,7 @@ func (r *relationship) 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 (r *relationship) getInternalBufferShallowCopy() []*Session {
+func (r *relationship) getInternalBufferShallowCopy() []*session.Session {
 	r.mux.RLock()
 	defer r.mux.RUnlock()
 	return r.sessions
@@ -397,7 +424,7 @@ func (r *relationship) clean() {
 
 	numConfirmed := uint(0)
 
-	var newSessions []*Session
+	var newSessions []*session.Session
 	editsMade := false
 
 	for _, s := range r.sessions {
diff --git a/storage/e2e/relationshipFingerprint.go b/e2e/ratchet/partner/relationshipFingerprint.go
similarity index 90%
rename from storage/e2e/relationshipFingerprint.go
rename to e2e/ratchet/partner/relationshipFingerprint.go
index 29b80896dfc078b8ab1a7cefa348a7860498aec2..0cceefc61cb8aa6e2e0b6e461689fff8e3b704a4 100644
--- a/storage/e2e/relationshipFingerprint.go
+++ b/e2e/ratchet/partner/relationshipFingerprint.go
@@ -5,10 +5,11 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package partner
 
 import (
 	jww "github.com/spf13/jwalterweatherman"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/storage/versioned"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/e2e"
@@ -16,16 +17,16 @@ import (
 	"gitlab.com/xx_network/primitives/netTime"
 )
 
-func makeRelationshipFingerprint(t RelationshipType, grp *cyclic.Group,
+func makeRelationshipFingerprint(t session2.RelationshipType, grp *cyclic.Group,
 	myPrivKey, partnerPubKey *cyclic.Int, me, partner *id.ID) []byte {
 
 	myPubKey := grp.ExpG(myPrivKey, grp.NewIntFromUInt(1))
 
 	switch t {
-	case Send:
+	case session2.Send:
 		return e2e.MakeRelationshipFingerprint(myPubKey, partnerPubKey,
 			me, partner)
-	case Receive:
+	case session2.Receive:
 		return e2e.MakeRelationshipFingerprint(myPubKey, partnerPubKey,
 			partner, me)
 	default:
diff --git a/storage/e2e/relationship_test.go b/e2e/ratchet/partner/relationship_test.go
similarity index 77%
rename from storage/e2e/relationship_test.go
rename to e2e/ratchet/partner/relationship_test.go
index bd21292259eae2cce4b1e82401bd4d002032a236..662951ac7374b443aa1a62e4170409353b0171e3 100644
--- a/storage/e2e/relationship_test.go
+++ b/e2e/ratchet/partner/relationship_test.go
@@ -5,11 +5,14 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package partner
 
 import (
 	"bytes"
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/e2e/ratchet"
+	session7 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	session6 "gitlab.com/elixxir/client/e2e/ratchet/session"
 	"gitlab.com/elixxir/client/interfaces/params"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/client/storage/versioned"
@@ -23,7 +26,7 @@ import (
 // Subtest: unmarshal/marshal with one session in the buff
 func TestRelationship_MarshalUnmarshal(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 
 	// Serialization should include session slice only
 	serialized, err := sb.marshal()
@@ -35,8 +38,8 @@ func TestRelationship_MarshalUnmarshal(t *testing.T) {
 		manager:     mgr,
 		t:           0,
 		kv:          sb.kv,
-		sessions:    make([]*Session, 0),
-		sessionByID: make(map[SessionID]*Session),
+		sessions:    make([]*session7.Session, 0),
+		sessionByID: make(map[session7.SessionID]*session7.Session),
 	}
 
 	err = sb2.unmarshal(serialized)
@@ -53,14 +56,14 @@ func TestRelationship_MarshalUnmarshal(t *testing.T) {
 // 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, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 
 	err := sb.save()
 	if err != nil {
 		t.Fatal(err)
 	}
 
-	sb2, err := LoadRelationship(mgr, Send)
+	sb2, err := LoadRelationship(mgr, session7.Send)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -75,13 +78,13 @@ func TestDeleteRelationship(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
 
 	// Generate send relationship
-	mgr.send = NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	mgr.send = NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 	if err := mgr.send.save(); err != nil {
 		t.Fatal(err)
 	}
 
 	// Generate receive relationship
-	mgr.receive = NewRelationship(mgr, Receive, params.GetDefaultE2ESessionParams())
+	mgr.receive = NewRelationship(mgr, session7.Receive, params.GetDefaultE2ESessionParams())
 	if err := mgr.receive.save(); err != nil {
 		t.Fatal(err)
 	}
@@ -91,12 +94,12 @@ func TestDeleteRelationship(t *testing.T) {
 		t.Fatalf("DeleteRelationship error: Could not delete manager: %v", err)
 	}
 
-	_, err = LoadRelationship(mgr, Send)
+	_, err = LoadRelationship(mgr, session7.Send)
 	if err == nil {
 		t.Fatalf("DeleteRelationship error: Should not have loaded deleted relationship: %v", err)
 	}
 
-	_, err = LoadRelationship(mgr, Receive)
+	_, err = LoadRelationship(mgr, session7.Receive)
 	if err == nil {
 		t.Fatalf("DeleteRelationship error: Should not have loaded deleted relationship: %v", err)
 	}
@@ -112,7 +115,7 @@ func TestRelationship_deleteRelationshipFingerprint(t *testing.T) {
 	}()
 
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 
 	err := sb.save()
 	if err != nil {
@@ -131,7 +134,7 @@ func TestRelationship_deleteRelationshipFingerprint(t *testing.T) {
 // Shows that Relationship returns a valid session buff
 func TestNewRelationshipBuff(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 	if mgr != sb.manager {
 		t.Error("managers should be identical")
 	}
@@ -148,21 +151,21 @@ func TestNewRelationshipBuff(t *testing.T) {
 // Shows that AddSession adds one session to the relationship
 func TestRelationship_AddSession(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 	if len(sb.sessions) != 1 {
 		t.Error("starting session slice length should be 1")
 	}
 	if len(sb.sessionByID) != 1 {
 		t.Error("starting session map length should be 1")
 	}
-	session, _ := makeTestSession()
+	session, _ := session6.makeTestSession()
 	// 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 relationship (which is not the case in
 	// this test.)
 	sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
-		session.partnerSource, Sending, session.e2eParams)
+		session.partnerSource, session7.Sending, session.e2eParams)
 	if len(sb.sessions) != 2 {
 		t.Error("ending session slice length should be 2")
 	}
@@ -177,7 +180,7 @@ func TestRelationship_AddSession(t *testing.T) {
 // GetNewest should get the session that was most recently added to the buff
 func TestRelationship_GetNewest(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 	// The newest session should be nil upon session buffer creation
 	nilSession := sb.GetNewest()
 	if nilSession == nil {
@@ -185,18 +188,18 @@ func TestRelationship_GetNewest(t *testing.T) {
 			"with one session")
 	}
 
-	session, _ := makeTestSession()
+	session, _ := session6.makeTestSession()
 	sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
-		session.partnerSource, Sending, session.e2eParams)
+		session.partnerSource, session7.Sending, session.e2eParams)
 	if session.GetID() != sb.GetNewest().GetID() {
 		t.Error("session added should have same ID")
 	}
 
-	session2, _ := makeTestSession()
+	session2, _ := session6.makeTestSession()
 	sb.AddSession(session2.myPrivKey, session2.partnerPubKey, nil,
 		session2.mySIDHPrivKey, session2.partnerSIDHPubKey,
-		session2.partnerSource, Sending, session.e2eParams)
+		session2.partnerSource, session7.Sending, session.e2eParams)
 	if session2.GetID() != sb.GetNewest().GetID() {
 		t.Error("session added should have same ID")
 	}
@@ -206,13 +209,13 @@ func TestRelationship_GetNewest(t *testing.T) {
 // Shows that Confirm confirms the specified session in the buff
 func TestRelationship_Confirm(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
-	session, _ := makeTestSession()
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
+	session, _ := session6.makeTestSession()
 
 	sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
-		session.partnerSource, Sending, session.e2eParams)
-	sb.sessions[1].negotiationStatus = Sent
+		session.partnerSource, session7.Sending, session.e2eParams)
+	sb.sessions[1].negotiationStatus = session7.Sent
 
 	if sb.sessions[1].IsConfirmed() {
 		t.Error("session should not be confirmed before confirmation")
@@ -231,8 +234,8 @@ func TestRelationship_Confirm(t *testing.T) {
 // Shows that the session buff returns an error when the session doesn't exist
 func TestRelationship_Confirm_Err(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
-	session, _ := makeTestSession()
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
+	session, _ := session6.makeTestSession()
 
 	err := sb.Confirm(session.GetID())
 	if err == nil {
@@ -243,11 +246,11 @@ func TestRelationship_Confirm_Err(t *testing.T) {
 // Shows that a session can get got by ID from the buff
 func TestRelationship_GetByID(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
-	session, _ := makeTestSession()
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
+	session, _ := session6.makeTestSession()
 	session = sb.AddSession(session.myPrivKey, session.partnerPubKey, nil,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
-		session.partnerSource, Sending, session.e2eParams)
+		session.partnerSource, session7.Sending, session.e2eParams)
 	session2 := sb.GetByID(session.GetID())
 	if !reflect.DeepEqual(session, session2) {
 		t.Error("gotten session should be the same")
@@ -258,8 +261,8 @@ func TestRelationship_GetByID(t *testing.T) {
 // returning sessions that are confirmed and past rekeyThreshold
 func TestRelationship_GetNewestRekeyableSession(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
-	sb.sessions[0].negotiationStatus = Unconfirmed
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
+	sb.sessions[0].negotiationStatus = session7.Unconfirmed
 	// no available rekeyable sessions: nil
 	session2 := sb.getNewestRekeyableSession()
 	if session2 != sb.sessions[0] {
@@ -267,11 +270,11 @@ func TestRelationship_GetNewestRekeyableSession(t *testing.T) {
 	}
 
 	// add a rekeyable session: that session
-	session, _ := makeTestSession()
+	session, _ := session6.makeTestSession()
 	sb.AddSession(session.myPrivKey, session.partnerPubKey, session.baseKey,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
-		session.partnerSource, Sending, session.e2eParams)
-	sb.sessions[0].negotiationStatus = Confirmed
+		session.partnerSource, session7.Sending, session.e2eParams)
+	sb.sessions[0].negotiationStatus = session7.Confirmed
 	session3 := sb.getNewestRekeyableSession()
 
 	if session3 == nil {
@@ -282,15 +285,15 @@ func TestRelationship_GetNewestRekeyableSession(t *testing.T) {
 
 	// add another rekeyable session: that session
 	// show the newest session is selected
-	additionalSession, _ := makeTestSession()
+	additionalSession, _ := session6.makeTestSession()
 	sb.AddSession(additionalSession.myPrivKey,
 		additionalSession.partnerPubKey, nil,
 		additionalSession.mySIDHPrivKey,
 		additionalSession.partnerSIDHPubKey,
 		additionalSession.partnerSource,
-		Sending, additionalSession.e2eParams)
+		session7.Sending, additionalSession.e2eParams)
 
-	sb.sessions[0].negotiationStatus = Confirmed
+	sb.sessions[0].negotiationStatus = session7.Confirmed
 
 	session4 := sb.getNewestRekeyableSession()
 	if session4 == nil {
@@ -301,7 +304,7 @@ func TestRelationship_GetNewestRekeyableSession(t *testing.T) {
 
 	// make the very newest session unrekeyable: the previous session
 	// sb.sessions[1].negotiationStatus = Confirmed
-	sb.sessions[0].negotiationStatus = Unconfirmed
+	sb.sessions[0].negotiationStatus = session7.Unconfirmed
 
 	session5 := sb.getNewestRekeyableSession()
 	if session5 == nil {
@@ -314,10 +317,10 @@ func TestRelationship_GetNewestRekeyableSession(t *testing.T) {
 // Shows that GetSessionForSending follows the hierarchy of sessions correctly
 func TestRelationship_GetSessionForSending(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 
-	sb.sessions = make([]*Session, 0)
-	sb.sessionByID = make(map[SessionID]*Session)
+	sb.sessions = make([]*session7.Session, 0)
+	sb.sessionByID = make(map[session7.SessionID]*session7.Session)
 
 	none := sb.getSessionForSending()
 	if none != nil {
@@ -325,15 +328,15 @@ func TestRelationship_GetSessionForSending(t *testing.T) {
 	}
 
 	// First case: unconfirmed rekey
-	unconfirmedRekey, _ := makeTestSession()
+	unconfirmedRekey, _ := session6.makeTestSession()
 
 	sb.AddSession(unconfirmedRekey.myPrivKey, unconfirmedRekey.partnerPubKey,
 		unconfirmedRekey.partnerPubKey, // FIXME? Shoudln't this be nil?
 		unconfirmedRekey.mySIDHPrivKey,
 		unconfirmedRekey.partnerSIDHPubKey,
 		unconfirmedRekey.partnerSource,
-		Sending, unconfirmedRekey.e2eParams)
-	sb.sessions[0].negotiationStatus = Unconfirmed
+		session7.Sending, unconfirmedRekey.e2eParams)
+	sb.sessions[0].negotiationStatus = session7.Unconfirmed
 	sb.sessions[0].keyState.SetNumKeysTEST(2000, t)
 	sb.sessions[0].rekeyThreshold = 1000
 	sb.sessions[0].keyState.SetNumAvailableTEST(600, t)
@@ -341,14 +344,14 @@ func TestRelationship_GetSessionForSending(t *testing.T) {
 	if sending.GetID() != sb.sessions[0].GetID() {
 		t.Error("got an unexpected session")
 	}
-	if sending.Status() != RekeyNeeded || sending.IsConfirmed() {
+	if sending.Status() != session7.RekeyNeeded || sending.IsConfirmed() {
 		t.Errorf("returned session is expected to be 'RekeyNedded' "+
 			"'Unconfirmed', it is: %s, confirmed: %v", sending.Status(),
 			sending.IsConfirmed())
 	}
 
 	// Second case: unconfirmed active
-	unconfirmedActive, _ := makeTestSession()
+	unconfirmedActive, _ := session6.makeTestSession()
 
 	sb.AddSession(unconfirmedActive.myPrivKey,
 		unconfirmedActive.partnerPubKey,
@@ -356,8 +359,8 @@ func TestRelationship_GetSessionForSending(t *testing.T) {
 		unconfirmedActive.mySIDHPrivKey,
 		unconfirmedActive.partnerSIDHPubKey,
 		unconfirmedActive.partnerSource,
-		Sending, unconfirmedActive.e2eParams)
-	sb.sessions[0].negotiationStatus = Unconfirmed
+		session7.Sending, unconfirmedActive.e2eParams)
+	sb.sessions[0].negotiationStatus = session7.Unconfirmed
 	sb.sessions[0].keyState.SetNumKeysTEST(2000, t)
 	sb.sessions[0].rekeyThreshold = 1000
 	sb.sessions[0].keyState.SetNumAvailableTEST(2000, t)
@@ -366,22 +369,22 @@ func TestRelationship_GetSessionForSending(t *testing.T) {
 		t.Error("got an unexpected session")
 	}
 
-	if sending.Status() != Active || sending.IsConfirmed() {
+	if sending.Status() != session7.Active || sending.IsConfirmed() {
 		t.Errorf("returned session is expected to be 'Active' "+
 			"'Unconfirmed', it is: %s, confirmed: %v", sending.Status(),
 			sending.IsConfirmed())
 	}
 
 	// Third case: confirmed rekey
-	confirmedRekey, _ := makeTestSession()
+	confirmedRekey, _ := session6.makeTestSession()
 
 	sb.AddSession(confirmedRekey.myPrivKey, confirmedRekey.partnerPubKey,
 		confirmedRekey.partnerPubKey,
 		confirmedRekey.mySIDHPrivKey,
 		confirmedRekey.partnerSIDHPubKey,
 		confirmedRekey.partnerSource,
-		Sending, confirmedRekey.e2eParams)
-	sb.sessions[0].negotiationStatus = Confirmed
+		session7.Sending, confirmedRekey.e2eParams)
+	sb.sessions[0].negotiationStatus = session7.Confirmed
 	sb.sessions[0].keyState.SetNumKeysTEST(2000, t)
 	sb.sessions[0].rekeyThreshold = 1000
 	sb.sessions[0].keyState.SetNumAvailableTEST(600, t)
@@ -389,22 +392,22 @@ func TestRelationship_GetSessionForSending(t *testing.T) {
 	if sending.GetID() != sb.sessions[0].GetID() {
 		t.Error("got an unexpected session")
 	}
-	if sending.Status() != RekeyNeeded || !sending.IsConfirmed() {
+	if sending.Status() != session7.RekeyNeeded || !sending.IsConfirmed() {
 		t.Errorf("returned session is expected to be 'RekeyNeeded' "+
 			"'Confirmed', it is: %s, confirmed: %v", sending.Status(),
 			sending.IsConfirmed())
 	}
 
 	// Fourth case: confirmed active
-	confirmedActive, _ := makeTestSession()
+	confirmedActive, _ := session6.makeTestSession()
 	sb.AddSession(confirmedActive.myPrivKey, confirmedActive.partnerPubKey,
 		confirmedActive.partnerPubKey,
 		confirmedActive.mySIDHPrivKey,
 		confirmedActive.partnerSIDHPubKey,
 		confirmedActive.partnerSource,
-		Sending, confirmedActive.e2eParams)
+		session7.Sending, confirmedActive.e2eParams)
 
-	sb.sessions[0].negotiationStatus = Confirmed
+	sb.sessions[0].negotiationStatus = session7.Confirmed
 	sb.sessions[0].keyState.SetNumKeysTEST(2000, t)
 	sb.sessions[0].keyState.SetNumAvailableTEST(2000, t)
 	sb.sessions[0].rekeyThreshold = 1000
@@ -412,7 +415,7 @@ func TestRelationship_GetSessionForSending(t *testing.T) {
 	if sending.GetID() != sb.sessions[0].GetID() {
 		t.Errorf("got an unexpected session of state: %s", sending.Status())
 	}
-	if sending.Status() != Active || !sending.IsConfirmed() {
+	if sending.Status() != session7.Active || !sending.IsConfirmed() {
 		t.Errorf("returned session is expected to be 'Active' "+
 			"'Confirmed', it is: %s, confirmed: %v", sending.Status(),
 			sending.IsConfirmed())
@@ -422,10 +425,10 @@ func TestRelationship_GetSessionForSending(t *testing.T) {
 // Shows that GetKeyForRekey returns a key if there's an appropriate session for rekeying
 func TestSessionBuff_GetKeyForRekey(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 
-	sb.sessions = make([]*Session, 0)
-	sb.sessionByID = make(map[SessionID]*Session)
+	sb.sessions = make([]*session7.Session, 0)
+	sb.sessionByID = make(map[session7.SessionID]*session7.Session)
 
 	// no available rekeyable sessions: error
 	key, err := sb.getKeyForRekey()
@@ -436,13 +439,13 @@ func TestSessionBuff_GetKeyForRekey(t *testing.T) {
 		t.Error("shouldn't have returned a key with no sessions available")
 	}
 
-	session, _ := makeTestSession()
+	session, _ := session6.makeTestSession()
 	sb.AddSession(session.myPrivKey, session.partnerPubKey,
 		session.partnerPubKey,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
 		session.partnerSource,
-		Sending, session.e2eParams)
-	sb.sessions[0].negotiationStatus = Confirmed
+		session7.Sending, session.e2eParams)
+	sb.sessions[0].negotiationStatus = session7.Confirmed
 	key, err = sb.getKeyForRekey()
 	if err != nil {
 		t.Error(err)
@@ -455,10 +458,10 @@ 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 := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
 
-	sb.sessions = make([]*Session, 0)
-	sb.sessionByID = make(map[SessionID]*Session)
+	sb.sessions = make([]*session7.Session, 0)
+	sb.sessionByID = make(map[session7.SessionID]*session7.Session)
 
 	// no available rekeyable sessions: error
 	key, err := sb.getKeyForSending()
@@ -469,12 +472,12 @@ func TestSessionBuff_GetKeyForSending(t *testing.T) {
 		t.Error("shouldn't have returned a key with no sessions available")
 	}
 
-	session, _ := makeTestSession()
+	session, _ := session6.makeTestSession()
 	sb.AddSession(session.myPrivKey, session.partnerPubKey,
 		session.partnerPubKey,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
 		session.partnerSource,
-		Sending, session.e2eParams)
+		session7.Sending, session.e2eParams)
 	key, err = sb.getKeyForSending()
 	if err != nil {
 		t.Error(err)
@@ -487,31 +490,31 @@ func TestSessionBuff_GetKeyForSending(t *testing.T) {
 // Shows that TriggerNegotiation sets up for negotiation correctly
 func TestSessionBuff_TriggerNegotiation(t *testing.T) {
 	mgr := makeTestRelationshipManager(t)
-	sb := NewRelationship(mgr, Send, params.GetDefaultE2ESessionParams())
-	sb.sessions = make([]*Session, 0)
-	sb.sessionByID = make(map[SessionID]*Session)
+	sb := NewRelationship(mgr, session7.Send, params.GetDefaultE2ESessionParams())
+	sb.sessions = make([]*session7.Session, 0)
+	sb.sessionByID = make(map[session7.SessionID]*session7.Session)
 
-	session, _ := makeTestSession()
+	session, _ := session6.makeTestSession()
 	session = sb.AddSession(session.myPrivKey, session.partnerPubKey,
 		session.partnerPubKey,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
 		session.partnerSource,
-		Sending, session.e2eParams)
-	session.negotiationStatus = Confirmed
+		session7.Sending, session.e2eParams)
+	session.negotiationStatus = session7.Confirmed
 	// The added session isn't ready for rekey, so it's not returned here
 	negotiations := sb.TriggerNegotiation()
 	if len(negotiations) != 0 {
 		t.Errorf("should have had zero negotiations: %+v", negotiations)
 	}
-	session2, _ := makeTestSession()
+	session2, _ := session6.makeTestSession()
 	// Make only a few keys available to trigger the rekeyThreshold
 	session2 = sb.AddSession(session2.myPrivKey, session2.partnerPubKey,
 		session2.partnerPubKey,
 		session.mySIDHPrivKey, session.partnerSIDHPubKey,
 		session2.partnerSource,
-		Sending, session2.e2eParams)
+		session7.Sending, session2.e2eParams)
 	session2.keyState.SetNumAvailableTEST(4, t)
-	session2.negotiationStatus = Confirmed
+	session2.negotiationStatus = session7.Confirmed
 	negotiations = sb.TriggerNegotiation()
 	if len(negotiations) != 1 {
 		t.Fatal("should have had one negotiation")
@@ -520,24 +523,24 @@ func TestSessionBuff_TriggerNegotiation(t *testing.T) {
 		t.Error("negotiated sessions should include the rekeyable " +
 			"session")
 	}
-	if session2.negotiationStatus != NewSessionTriggered {
+	if session2.negotiationStatus != session7.NewSessionTriggered {
 		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, _ := session6.makeTestSession()
 
 	session3 = sb.AddSession(session3.myPrivKey, session3.partnerPubKey,
 		session3.partnerPubKey,
 		session3.mySIDHPrivKey, session3.partnerSIDHPubKey,
 		session3.partnerSource,
-		Sending, session3.e2eParams)
-	session3.negotiationStatus = Unconfirmed
+		session7.Sending, session3.e2eParams)
+	session3.negotiationStatus = session7.Unconfirmed
 
 	// Set session 2 status back to Confirmed to show that more than one session can be returned
-	session2.negotiationStatus = Confirmed
+	session2.negotiationStatus = session7.Confirmed
 	// Trigger negotiations
 	negotiations = sb.TriggerNegotiation()
 
@@ -548,7 +551,7 @@ func TestSessionBuff_TriggerNegotiation(t *testing.T) {
 	for i := range negotiations {
 		if negotiations[i].GetID() == session3.GetID() {
 			found = true
-			if negotiations[i].negotiationStatus != Sending {
+			if negotiations[i].negotiationStatus != session7.Sending {
 				t.Error("triggering negotiation should change session3 to sending")
 			}
 		}
@@ -578,10 +581,10 @@ func makeTestRelationshipManager(t *testing.T) *Manager {
 	mySIDHPubKey := util.NewSIDHPublicKey(sidh.KeyVariantSidhB)
 	mySIDHPrivKey.Generate(rng)
 	mySIDHPrivKey.GeneratePublicKey(mySIDHPubKey)
-	fps := newFingerprints()
-	g := getGroup()
+	fps := ratchet.newFingerprints()
+	g := session6.getGroup()
 	return &Manager{
-		ctx: &context{
+		ctx: &ratchet.context{
 			fa:   &fps,
 			grp:  g,
 			myID: &id.ID{},
@@ -596,7 +599,7 @@ func makeTestRelationshipManager(t *testing.T) *Manager {
 }
 
 // Revises a session to fit a sessionbuff and saves it to the sessionbuff's kv store
-func adaptToBuff(session *Session, buff *relationship, t *testing.T) {
+func adaptToBuff(session *session7.Session, buff *relationship, t *testing.T) {
 	session.relationship = buff
 	session.keyState.SetKvTEST(buff.manager.kv, t)
 	err := session.keyState.SaveTEST(t)
diff --git a/storage/e2e/key.go b/e2e/ratchet/partner/session/cypher.go
similarity index 90%
rename from storage/e2e/key.go
rename to e2e/ratchet/partner/session/cypher.go
index bd203c88e9c16d21224feda8181c77adaa8be0de..34ee21885ddd66e9e621c9dae027854837d2ea83 100644
--- a/storage/e2e/key.go
+++ b/e2e/ratchet/partner/session/cypher.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import (
 	"github.com/cloudflare/circl/dh/sidh"
@@ -50,7 +50,7 @@ func GenerateE2ESessionBaseKey(myDHPrivKey, theirDHPubKey *cyclic.Int,
 	return baseKey
 }
 
-type Key struct {
+type Cypher struct {
 	// Links
 	session *Session
 
@@ -61,21 +61,21 @@ type Key struct {
 	keyNum uint32
 }
 
-func newKey(session *Session, keynum uint32) *Key {
-	return &Key{
+func newKey(session *Session, keynum uint32) *Cypher {
+	return &Cypher{
 		session: session,
 		keyNum:  keynum,
 	}
 }
 
 // return pointers to higher level management structures
-func (k *Key) GetSession() *Session { return k.session }
+func (k *Cypher) GetSession() *Session { return k.session }
 
 // returns the key fingerprint if it has it, otherwise generates it
 // this function does not memoize the fingerprint if it doesnt have it because
 // in most cases it will not be used for a long time and as a result should not
 // be stored in ram.
-func (k *Key) Fingerprint() format.Fingerprint {
+func (k *Cypher) Fingerprint() format.Fingerprint {
 	if k.fp != nil {
 		return *k.fp
 	}
@@ -86,7 +86,7 @@ func (k *Key) Fingerprint() format.Fingerprint {
 // the E2E key to encrypt msg to its intended recipient
 // It also properly populates the associated data, including the MAC, fingerprint,
 // and encrypted timestamp
-func (k *Key) Encrypt(msg format.Message) format.Message {
+func (k *Cypher) Encrypt(msg format.Message) format.Message {
 	fp := k.Fingerprint()
 	key := k.generateKey()
 
@@ -109,7 +109,7 @@ func (k *Key) Encrypt(msg format.Message) format.Message {
 // Decrypt uses the E2E key to decrypt the message
 // It returns an error in case of HMAC verification failure
 // or in case of a decryption error (related to padding)
-func (k *Key) Decrypt(msg format.Message) (format.Message, error) {
+func (k *Cypher) Decrypt(msg format.Message) (format.Message, error) {
 	fp := k.Fingerprint()
 	key := k.generateKey()
 
@@ -128,13 +128,13 @@ func (k *Key) Decrypt(msg format.Message) (format.Message, error) {
 }
 
 // Sets the key as used
-func (k *Key) denoteUse() {
+func (k *Cypher) denoteUse() {
 	k.session.useKey(k.keyNum)
 }
 
 // generateKey derives the current e2e key from the baseKey and the index
 // keyNum and returns it
-func (k *Key) generateKey() e2eCrypto.Key {
+func (k *Cypher) generateKey() e2eCrypto.Key {
 	return e2eCrypto.DeriveKey(k.session.baseKey, k.keyNum,
 		k.session.relationshipFingerprint)
 }
diff --git a/e2e/ratchet/partner/session/cypherHandler.go b/e2e/ratchet/partner/session/cypherHandler.go
new file mode 100644
index 0000000000000000000000000000000000000000..535d5ac63dd39bcfff24db572633874a87d2b02e
--- /dev/null
+++ b/e2e/ratchet/partner/session/cypherHandler.go
@@ -0,0 +1,6 @@
+package session
+
+type CypherHandler interface {
+	AddKey(k *Cypher)
+	DeleteKey(k *Cypher)
+}
diff --git a/storage/e2e/key_test.go b/e2e/ratchet/partner/session/cypher_test.go
similarity index 96%
rename from storage/e2e/key_test.go
rename to e2e/ratchet/partner/session/cypher_test.go
index acf235b0ed7ddba596faaf27d6109a1273c29d6c..26d3b104aa6427ef1ab500f3225eefd3d447748f 100644
--- a/storage/e2e/key_test.go
+++ b/e2e/ratchet/partner/session/cypher_test.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import (
 	"bytes"
@@ -68,7 +68,7 @@ func TestGenerateE2ESessionBaseKey(t *testing.T) {
 
 // Happy path of newKey().
 func Test_newKey(t *testing.T) {
-	expectedKey := &Key{
+	expectedKey := &Cypher{
 		session: getSession(t),
 		keyNum:  rand.Uint32(),
 	}
@@ -134,7 +134,7 @@ func TestKey_EncryptDecrypt(t *testing.T) {
 	prng := rand.New(rand.NewSource(42))
 
 	for i := 0; i < numTests; i++ {
-		// generate the baseKey and session
+		// finalizeKeyNegotation the baseKey and session
 		privateKey := dh.GeneratePrivateKey(dh.DefaultPrivateKeyLength, grp, rng)
 		publicKey := dh.GeneratePublicKey(privateKey, grp)
 		baseKey := dh.GenerateSessionKey(privateKey, publicKey, grp)
@@ -229,7 +229,7 @@ func getSession(t *testing.T) *Session {
 	grp := getGroup()
 	rng := csprng.NewSystemRNG()
 
-	// generate the baseKey and session
+	// finalizeKeyNegotation the baseKey and session
 	privateKey := dh.GeneratePrivateKey(dh.DefaultPrivateKeyLength, grp, rng)
 	publicKey := dh.GeneratePublicKey(privateKey, grp)
 
@@ -246,21 +246,12 @@ func getSession(t *testing.T) *Session {
 	baseKey := GenerateE2ESessionBaseKey(privateKey, publicKey, grp, privA,
 		pubB)
 
-	fps := newFingerprints()
-	ctx := &context{
-		fa:  &fps,
-		grp: grp,
-	}
-
 	keyState, err := utility.NewStateVector(versioned.NewKV(make(ekv.Memstore)), "keyState", rand.Uint32())
 	if err != nil {
 		panic(err)
 	}
 
 	return &Session{
-		relationship: &relationship{
-			manager: &Manager{ctx: ctx},
-		},
 		baseKey:  baseKey,
 		keyState: keyState,
 	}
diff --git a/storage/e2e/negotiation.go b/e2e/ratchet/partner/session/negotiation.go
similarity index 98%
rename from storage/e2e/negotiation.go
rename to e2e/ratchet/partner/session/negotiation.go
index 783f6a04a16d537ca230a8a01287d7198185fe19..103d3feda5535b277968be2eb0f5a7b5796c995f 100644
--- a/storage/e2e/negotiation.go
+++ b/e2e/ratchet/partner/session/negotiation.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import "fmt"
 
diff --git a/e2e/ratchet/partner/session/params.go b/e2e/ratchet/partner/session/params.go
new file mode 100644
index 0000000000000000000000000000000000000000..756bff1fa0a1129fd9c1874e22a9759a0ffbc4bd
--- /dev/null
+++ b/e2e/ratchet/partner/session/params.go
@@ -0,0 +1,41 @@
+package session
+
+import "fmt"
+
+type Params struct {
+	// using the DH as a seed, both sides finalizeKeyNegotation a number
+	// of keys to use before they must rekey because
+	// there are no keys to use.
+	MinKeys uint16
+	MaxKeys uint16
+	// the percent of keys before a rekey is attempted. must be <0
+	RekeyThreshold float64
+	// extra keys generated and reserved for rekey attempts. This
+	// many keys are not allowed to be used for sending messages
+	// in order to ensure there are extras for rekeying.
+	NumRekeys uint16
+}
+
+// DEFAULT KEY GENERATION PARAMETERS
+// Hardcoded limits for keys
+// sets the number of keys very high, but with a low rekey threshold. In this case, if the other party is online, you will read
+const (
+	minKeys       uint16  = 1000
+	maxKeys       uint16  = 2000
+	rekeyThrshold float64 = 0.05
+	numReKeys     uint16  = 16
+)
+
+func GetDefaultE2ESessionParams() Params {
+	return Params{
+		MinKeys:        minKeys,
+		MaxKeys:        maxKeys,
+		RekeyThreshold: rekeyThrshold,
+		NumRekeys:      numReKeys,
+	}
+}
+
+func (p Params) String() string {
+	return fmt.Sprintf("SessionParams{ MinKeys: %d, MaxKeys: %d, NumRekeys: %d }",
+		p.MinKeys, p.MaxKeys, p.NumRekeys)
+}
diff --git a/storage/e2e/relationshipType.go b/e2e/ratchet/partner/session/relationshipType.go
similarity index 88%
rename from storage/e2e/relationshipType.go
rename to e2e/ratchet/partner/session/relationshipType.go
index 5fb5980f1f1affde2165328aa719fb16ff40b1d4..cb2220ad40f01a6508184ac520dd980d7f0c4cf8 100644
--- a/storage/e2e/relationshipType.go
+++ b/e2e/ratchet/partner/session/relationshipType.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import (
 	"fmt"
@@ -30,14 +30,14 @@ func (rt RelationshipType) String() string {
 	}
 }
 
-func (rt RelationshipType) prefix() string {
+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)
+		jww.FATAL.Panicf("No Prefix for relationship type: %s", rt)
 	}
 	return ""
 }
diff --git a/storage/e2e/session.go b/e2e/ratchet/partner/session/session.go
similarity index 87%
rename from storage/e2e/session.go
rename to e2e/ratchet/partner/session/session.go
index 8238b090d17db4bccf63cc1689b45ff18d9651a8..8f0605741225beb0cca6294c38cf3d501c94c1c4 100644
--- a/storage/e2e/session.go
+++ b/e2e/ratchet/partner/session/session.go
@@ -5,26 +5,26 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import (
+	"encoding/binary"
 	"encoding/json"
 	"fmt"
 	"github.com/cloudflare/circl/dh/sidh"
 	"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"
+	"gitlab.com/elixxir/crypto/fastRNG"
 	"gitlab.com/elixxir/crypto/hash"
 	"gitlab.com/xx_network/crypto/randomness"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
 	"math"
 	"math/big"
-	"math/rand"
 	"sync"
 	"testing"
 )
@@ -34,12 +34,12 @@ const sessionPrefix = "session{ID:%s}"
 const sessionKey = "session"
 
 type Session struct {
-	//pointer to relationship
-	relationship *relationship
 	//prefixed kv
 	kv *versioned.KV
 	//params
-	e2eParams params.E2ESessionParams
+	e2eParams Params
+
+	sID SessionID
 
 	partner *id.ID
 
@@ -76,13 +76,18 @@ type Session struct {
 
 	//mutex
 	mux sync.RWMutex
+
+	//interfaces
+	cyHandler CypherHandler
+	grp       *cyclic.Group
+	rng       *fastRNG.StreamGenerator
 }
 
 // As this is serialized by json, any field that should be serialized
 // must be exported
 // Utility struct to write part of session data to disk
 type SessionDisk struct {
-	E2EParams params.E2ESessionParams
+	E2EParams Params
 
 	//session type
 	Type uint8
@@ -117,12 +122,14 @@ type SessionDisk struct {
 }
 
 /*CONSTRUCTORS*/
-//Generator which creates all keys and structures
-func newSession(ship *relationship, t RelationshipType, myPrivKey, partnerPubKey,
-	baseKey *cyclic.Int, mySIDHPrivKey *sidh.PrivateKey,
+
+//NewSession - Generator which creates all keys and structures
+func NewSession(kv *versioned.KV, t RelationshipType, partner *id.ID, myPrivKey,
+	partnerPubKey, baseKey *cyclic.Int, mySIDHPrivKey *sidh.PrivateKey,
 	partnerSIDHPubKey *sidh.PublicKey, trigger SessionID,
 	relationshipFingerprint []byte, negotiationStatus Negotiation,
-	e2eParams params.E2ESessionParams) *Session {
+	e2eParams Params, cyHandler CypherHandler, grp *cyclic.Group,
+	rng *fastRNG.StreamGenerator) *Session {
 
 	if e2eParams.MinKeys < 10 {
 		jww.FATAL.Panicf("Cannot create a session with a minimum "+
@@ -131,7 +138,6 @@ func newSession(ship *relationship, t RelationshipType, myPrivKey, partnerPubKey
 
 	session := &Session{
 		e2eParams:               e2eParams,
-		relationship:            ship,
 		t:                       t,
 		myPrivKey:               myPrivKey,
 		partnerPubKey:           partnerPubKey,
@@ -141,19 +147,23 @@ func newSession(ship *relationship, t RelationshipType, myPrivKey, partnerPubKey
 		relationshipFingerprint: relationshipFingerprint,
 		negotiationStatus:       negotiationStatus,
 		partnerSource:           trigger,
-		partner:                 ship.manager.partner.DeepCopy(),
+		partner:                 partner,
+		cyHandler:               cyHandler,
+		grp:                     grp,
+		rng:                     rng,
 	}
 
-	session.kv = session.generate(ship.kv)
+	session.finalizeKeyNegotiation()
+	session.kv = kv.Prefix(MakeSessionPrefix(session.sID))
+	session.buildChildKeys()
 
-	grp := session.relationship.manager.ctx.grp
 	myPubKey := dh.GeneratePublicKey(session.myPrivKey, grp)
 
 	jww.INFO.Printf("New Session with Partner %s:\n\tType: %s"+
 		"\n\tBaseKey: %s\n\tRelationship Fingerprint: %v\n\tNumKeys: %d"+
 		"\n\tMy Public Key: %s\n\tPartner Public Key: %s"+
 		"\n\tMy Public SIDH: %s\n\tPartner Public SIDH: %s",
-		ship.manager.partner,
+		partner,
 		t,
 		session.baseKey.TextVerbose(16, 0),
 		session.relationshipFingerprint,
@@ -163,22 +173,26 @@ func newSession(ship *relationship, t RelationshipType, myPrivKey, partnerPubKey
 		utility.StringSIDHPrivKey(session.mySIDHPrivKey),
 		utility.StringSIDHPubKey(session.partnerSIDHPubKey))
 
-	err := session.save()
+	err := session.Save()
 	if err != nil {
 		jww.FATAL.Printf("Failed to make new session for Partner %s: %s",
-			ship.manager.partner, err)
+			partner, err)
 	}
 
 	return session
 }
 
 // Load session and state vector from kv and populate runtime fields
-func loadSession(ship *relationship, kv *versioned.KV,
-	relationshipFingerprint []byte) (*Session, error) {
+func LoadSession(kv *versioned.KV, sessionID SessionID,
+	relationshipFingerprint []byte, cyHandler CypherHandler,
+	grp *cyclic.Group, rng *fastRNG.StreamGenerator) (*Session, error) {
 
 	session := Session{
-		relationship: ship,
-		kv:           kv,
+		kv:        kv.Prefix(MakeSessionPrefix(sessionID)),
+		sID:       sessionID,
+		cyHandler: cyHandler,
+		grp:       grp,
+		rng:       rng,
 	}
 
 	obj, err := kv.Get(sessionKey, currentSessionVersion)
@@ -197,19 +211,16 @@ func loadSession(ship *relationship, kv *versioned.KV,
 
 	if session.t == Receive {
 		// register key fingerprints
-		ship.manager.ctx.fa.add(session.getUnusedKeys())
+		for _, cy := range session.getUnusedKeys() {
+			cyHandler.AddKey(cy)
+		}
 	}
 	session.relationshipFingerprint = relationshipFingerprint
 
-	if !session.partner.Cmp(ship.manager.partner) {
-		return nil, errors.Errorf("Stored partner (%s) did not match "+
-			"relationship partner (%s)", session.partner, ship.manager.partner)
-	}
-
 	return &session, nil
 }
 
-func (s *Session) save() error {
+func (s *Session) Save() error {
 
 	now := netTime.Now()
 
@@ -235,7 +246,9 @@ func (s *Session) Delete() {
 	s.mux.Lock()
 	defer s.mux.Unlock()
 
-	s.relationship.manager.ctx.fa.remove(s.getUnusedKeys())
+	for _, cy := range s.getUnusedKeys() {
+		s.cyHandler.DeleteKey(cy)
+	}
 
 	stateVectorErr := s.keyState.Delete()
 	sessionErr := s.kv.Delete(sessionKey, currentSessionVersion)
@@ -281,16 +294,6 @@ func (s *Session) GetSource() SessionID {
 	return s.partnerSource
 }
 
-//underlying definition of session id
-func getSessionIDFromBaseKey(baseKey *cyclic.Int) SessionID {
-	// no lock is needed because this cannot be edited
-	sid := SessionID{}
-	h, _ := hash.NewCMixHash()
-	h.Write(baseKey.Bytes())
-	copy(sid[:], h.Sum(nil))
-	return sid
-}
-
 //underlying definition of session id
 // FOR TESTING PURPOSES ONLY
 func GetSessionIDFromBaseKeyForTesting(baseKey *cyclic.Int, i interface{}) SessionID {
@@ -305,13 +308,13 @@ func GetSessionIDFromBaseKeyForTesting(baseKey *cyclic.Int, i interface{}) Sessi
 
 //Blake2B hash of base key used for storage
 func (s *Session) GetID() SessionID {
-	return getSessionIDFromBaseKey(s.baseKey)
+	return s.sID
 }
 
 // returns the ID of the partner for this session
 func (s *Session) GetPartner() *id.ID {
-	if s.relationship != nil {
-		return s.relationship.manager.partner.DeepCopy()
+	if s.partner != nil {
+		return s.partner
 	} else {
 		return nil
 	}
@@ -364,7 +367,7 @@ func (s *Session) unmarshal(b []byte) error {
 		return err
 	}
 
-	grp := s.relationship.manager.ctx.grp
+	grp := s.grp
 
 	s.e2eParams = sd.E2EParams
 	s.t = RelationshipType(sd.Type)
@@ -403,7 +406,7 @@ func (s *Session) unmarshal(b []byte) error {
 //key usage
 // Pops the first unused key, skipping any which are denoted as used.
 // will return if the remaining keys are designated as rekeys
-func (s *Session) PopKey() (*Key, error) {
+func (s *Session) PopKey() (*Cypher, error) {
 	if s.keyState.GetNumAvailable() <= uint32(s.e2eParams.NumRekeys) {
 		return nil, errors.New("no more keys left, remaining reserved " +
 			"for rekey")
@@ -416,7 +419,7 @@ func (s *Session) PopKey() (*Key, error) {
 	return newKey(s, keyNum), nil
 }
 
-func (s *Session) PopReKey() (*Key, error) {
+func (s *Session) PopReKey() (*Cypher, error) {
 	keyNum, err := s.keyState.Next()
 	if err != nil {
 		return nil, err
@@ -459,7 +462,7 @@ func (s *Session) Status() Status {
 // will be redone if it was in the process of sending
 
 // Moving from Unconfirmed to Sending and from Confirmed to NewSessionTriggered
-// is handled by  Session.triggerNegotiation() which is called by the
+// is handled by  Session.TriggerNegotiation() which is called by the
 // Manager as part of Manager.TriggerNegotiations() and will be rejected
 // from this function
 
@@ -501,7 +504,7 @@ func (s *Session) TrySetNegotiationStatus(status Negotiation) error {
 
 	//save the status if appropriate
 	if save {
-		if err := s.save(); err != nil {
+		if err := s.Save(); err != nil {
 			jww.FATAL.Panicf("Failed to save Session %s when moving from %s to %s", s, oldStatus, status)
 		}
 	}
@@ -521,7 +524,7 @@ func (s *Session) TrySetNegotiationStatus(status Negotiation) error {
 // In order to ensure the session creation is not triggered again after the
 // reload, it is the responsibility of the caller to call
 // Session.SetConfirmationStatus(NewSessionCreated) .
-func (s *Session) triggerNegotiation() bool {
+func (s *Session) TriggerNegotiation() bool {
 	// Due to the fact that a read lock cannot be transitioned to a
 	// write lock, the state checks need to happen a second time because it
 	// is possible for another thread to take the read lock and update the
@@ -551,7 +554,7 @@ func (s *Session) triggerNegotiation() bool {
 			s.mux.Unlock()
 			return false
 		}
-	} else if s.negotiationStatus == Unconfirmed && rand.Uint64()%s.rekeyThreshold == 0 {
+	} else if s.negotiationStatus == Unconfirmed && decideIfResendRekey(s.rng, 1/10) {
 		// retrigger this sessions negotiation
 		s.mux.RUnlock()
 		s.mux.Lock()
@@ -604,14 +607,14 @@ func (s *Session) useKey(keynum uint32) {
 	s.keyState.Use(keynum)
 }
 
-// generates keys from the base data stored in the session object.
+// finalizeKeyNegotiation 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.relationship.manager.ctx.grp
+func (s *Session) finalizeKeyNegotiation() {
+	grp := s.grp
 
-	//generate private key if it is not present
+	//Generates private key if it is not present
 	if s.myPrivKey == nil {
-		stream := s.relationship.manager.ctx.rng.GetStream()
+		stream := s.rng.GetStream()
 		s.myPrivKey = dh.GeneratePrivateKey(len(grp.GetPBytes()),
 			grp, stream)
 		// get the variant opposite my partners variant
@@ -629,12 +632,14 @@ func (s *Session) generate(kv *versioned.KV) *versioned.KV {
 			s.partnerSIDHPubKey)
 	}
 
-	kv = kv.Prefix(makeSessionPrefix(s.GetID()))
+	s.sID = getSessionIDFromBaseKey(s.baseKey)
+}
 
+func (s *Session) buildChildKeys() {
 	p := s.e2eParams
 	h, _ := hash.NewCMixHash()
 
-	//generate rekeyThreshold and keying info
+	//generates rekeyThreshold and keying info
 	numKeys := uint32(randomness.RandInInterval(big.NewInt(
 		int64(p.MaxKeys-p.MinKeys)),
 		s.baseKey.Bytes(), h).Int64() + int64(p.MinKeys))
@@ -652,25 +657,24 @@ func (s *Session) generate(kv *versioned.KV) *versioned.KV {
 	// To generate the state vector key correctly,
 	// basekey must be computed as the session ID is the hash of basekey
 	var err error
-	s.keyState, err = utility.NewStateVector(kv, "", numKeys)
+	s.keyState, err = utility.NewStateVector(s.kv, "", numKeys)
 	if err != nil {
 		jww.FATAL.Printf("Failed key generation: %s", err)
 	}
 
 	//register keys for reception if this is a reception session
 	if s.t == Receive {
-		//register keys
-		s.relationship.manager.ctx.fa.add(s.getUnusedKeys())
+		for _, cy := range s.getUnusedKeys() {
+			s.cyHandler.AddKey(cy)
+		}
 	}
-
-	return kv
 }
 
 //returns key objects for all unused keys
-func (s *Session) getUnusedKeys() []*Key {
+func (s *Session) getUnusedKeys() []*Cypher {
 	keyNums := s.keyState.GetUnusedKeyNums()
 
-	keys := make([]*Key, len(keyNums))
+	keys := make([]*Cypher, len(keyNums))
 	for i, keyNum := range keyNums {
 		keys[i] = newKey(s, keyNum)
 	}
@@ -679,6 +683,16 @@ func (s *Session) getUnusedKeys() []*Key {
 }
 
 //builds the
-func makeSessionPrefix(sid SessionID) string {
+func MakeSessionPrefix(sid SessionID) string {
 	return fmt.Sprintf(sessionPrefix, sid)
 }
+
+func decideIfResendRekey(genRng *fastRNG.StreamGenerator, ratio float64) bool {
+	stream := genRng.GetStream()
+	b := make([]byte, 8)
+	stream.Read(b)
+	stream.Close()
+	randNum := binary.BigEndian.Uint64(b)
+	max := uint64(float64(math.MaxUint64) * ratio)
+	return randNum < max
+}
diff --git a/storage/e2e/sessionID.go b/e2e/ratchet/partner/session/sessionID.go
similarity index 72%
rename from storage/e2e/sessionID.go
rename to e2e/ratchet/partner/session/sessionID.go
index 00b8ebca5c4709dc12d06da89c247eafbb09894d..4dddea303df01963b2a6b2d2a4bacbee5a44b08a 100644
--- a/storage/e2e/sessionID.go
+++ b/e2e/ratchet/partner/session/sessionID.go
@@ -5,11 +5,13 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import (
 	"encoding/base64"
 	"github.com/pkg/errors"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/hash"
 )
 
 const sessionIDLen = 32
@@ -31,3 +33,13 @@ func (sid *SessionID) Unmarshal(b []byte) error {
 	copy(sid[:], b)
 	return nil
 }
+
+//underlying definition of session id
+func getSessionIDFromBaseKey(baseKey *cyclic.Int) SessionID {
+	// no lock is needed because this cannot be edited
+	sid := SessionID{}
+	h, _ := hash.NewCMixHash()
+	h.Write(baseKey.Bytes())
+	copy(sid[:], h.Sum(nil))
+	return sid
+}
diff --git a/storage/e2e/session_test.go b/e2e/ratchet/partner/session/session_test.go
similarity index 92%
rename from storage/e2e/session_test.go
rename to e2e/ratchet/partner/session/session_test.go
index 2719df3c7d28ee09726c0bb9eec31682e96b865c..141cc8ad2b85c82c87a95f891169c988fc479efa 100644
--- a/storage/e2e/session_test.go
+++ b/e2e/ratchet/partner/session/session_test.go
@@ -5,11 +5,13 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import (
 	"errors"
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/e2e/ratchet"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
 	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/storage/utility"
 	util "gitlab.com/elixxir/client/storage/utility"
@@ -38,8 +40,8 @@ func TestSession_generate_noPrivateKeyReceive(t *testing.T) {
 	partnerSIDHPrivKey.GeneratePublicKey(partnerSIDHPubKey)
 
 	// create context objects for general use
-	fps := newFingerprints()
-	ctx := &context{
+	fps := ratchet.newFingerprints()
+	ctx := &ratchet.context{
 		fa:  &fps,
 		grp: grp,
 		rng: fastRNG.NewStreamGenerator(1, 0, csprng.NewSystemRNG),
@@ -50,14 +52,14 @@ func TestSession_generate_noPrivateKeyReceive(t *testing.T) {
 		partnerPubKey:     partnerPubKey,
 		partnerSIDHPubKey: partnerSIDHPubKey,
 		e2eParams:         params.GetDefaultE2ESessionParams(),
-		relationship: &relationship{
-			manager: &Manager{ctx: ctx},
+		relationship: &ratchet.relationship{
+			manager: &partner.Manager{ctx: ctx},
 		},
 		t: Receive,
 	}
 
-	// run the generate command
-	s.generate(versioned.NewKV(make(ekv.Memstore)))
+	// run the finalizeKeyNegotation command
+	s.finalizeKeyNegotation(versioned.NewKV(make(ekv.Memstore)))
 
 	// check that it generated a private key
 	if s.myPrivKey == nil {
@@ -110,8 +112,8 @@ func TestSession_generate_PrivateKeySend(t *testing.T) {
 	mySIDHPrivKey.GeneratePublicKey(mySIDHPubKey)
 
 	// create context objects for general use
-	fps := newFingerprints()
-	ctx := &context{
+	fps := ratchet.newFingerprints()
+	ctx := &ratchet.context{
 		fa:  &fps,
 		grp: grp,
 	}
@@ -123,14 +125,14 @@ func TestSession_generate_PrivateKeySend(t *testing.T) {
 		mySIDHPrivKey:     mySIDHPrivKey,
 		partnerSIDHPubKey: partnerSIDHPubKey,
 		e2eParams:         params.GetDefaultE2ESessionParams(),
-		relationship: &relationship{
-			manager: &Manager{ctx: ctx},
+		relationship: &ratchet.relationship{
+			manager: &partner.Manager{ctx: ctx},
 		},
 		t: Send,
 	}
 
-	// run the generate command
-	s.generate(versioned.NewKV(make(ekv.Memstore)))
+	// run the finalizeKeyNegotation command
+	s.finalizeKeyNegotation(versioned.NewKV(make(ekv.Memstore)))
 
 	// check that it generated a private key
 	if s.myPrivKey.Cmp(myPrivKey) != 0 {
@@ -164,13 +166,13 @@ func TestSession_generate_PrivateKeySend(t *testing.T) {
 	}
 }
 
-// Shows that newSession can result in all the fields being populated
+// Shows that NewSession can result in all the fields being populated
 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.relationship, sessionA.t,
+	sessionB := NewSession(sessionA.relationship, sessionA.t,
 		sessionA.myPrivKey, sessionA.partnerPubKey, sessionA.baseKey,
 		sessionA.mySIDHPrivKey, sessionA.partnerSIDHPubKey,
 		sessionA.GetID(), []byte(""), sessionA.negotiationStatus,
@@ -182,26 +184,26 @@ func TestNewSession(t *testing.T) {
 	}
 	// For everything else, just make sure it's populated
 	if sessionB.keyState == nil {
-		t.Error("newSession should populate keyState")
+		t.Error("NewSession should populate keyState")
 	}
 	if sessionB.relationship == nil {
-		t.Error("newSession should populate relationship")
+		t.Error("NewSession should populate relationship")
 	}
 	if sessionB.rekeyThreshold == 0 {
-		t.Error("newSession should populate rekeyThreshold")
+		t.Error("NewSession should populate rekeyThreshold")
 	}
 }
 
-// Shows that loadSession can result in all the fields being populated
+// Shows that LoadSession can result in all the fields being populated
 func TestSession_Load(t *testing.T) {
 	// Make a test session to easily populate all the fields
 	sessionA, _ := makeTestSession()
-	err := sessionA.save()
+	err := sessionA.Save()
 	if err != nil {
 		t.Fatal(err)
 	}
 	// Load another, hopefully identical session from the storage
-	sessionB, err := loadSession(sessionA.relationship, sessionA.kv, []byte(""))
+	sessionB, err := LoadSession(sessionA.relationship, sessionA.kv, []byte(""))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -210,7 +212,7 @@ func TestSession_Load(t *testing.T) {
 		t.Error(err)
 	}
 	// Key state should also be loaded and equivalent to the other session
-	// during loadSession()
+	// during LoadSession()
 	if !reflect.DeepEqual(sessionA.keyState, sessionB.keyState) {
 		t.Errorf("Two key states do not match.\nsessionA: %+v\nsessionB: %+v",
 			sessionA.keyState, sessionB.keyState)
@@ -233,8 +235,8 @@ func TestSession_Serialization(t *testing.T) {
 	}
 
 	sDeserialized := &Session{
-		relationship: &relationship{
-			manager: &Manager{ctx: ctx},
+		relationship: &ratchet.relationship{
+			manager: &partner.Manager{ctx: ctx},
 		},
 		kv: s.kv,
 	}
@@ -297,7 +299,7 @@ func TestSession_PopKey(t *testing.T) {
 // delete should remove unused keys from this session
 func TestSession_Delete(t *testing.T) {
 	s, _ := makeTestSession()
-	err := s.save()
+	err := s.Save()
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -537,7 +539,7 @@ func TestSession_TriggerNegotiation(t *testing.T) {
 	s.rekeyThreshold = 49
 	s.negotiationStatus = Confirmed
 
-	if !s.triggerNegotiation() {
+	if !s.TriggerNegotiation() {
 		t.Error("partnerSource negotiation unexpectedly failed")
 	}
 	if s.negotiationStatus != NewSessionTriggered {
@@ -548,7 +550,7 @@ func TestSession_TriggerNegotiation(t *testing.T) {
 	s.rekeyThreshold = 50
 	s.negotiationStatus = Confirmed
 
-	if !s.triggerNegotiation() {
+	if !s.TriggerNegotiation() {
 		t.Error("partnerSource negotiation unexpectedly failed")
 	}
 	if s.negotiationStatus != NewSessionTriggered {
@@ -559,7 +561,7 @@ func TestSession_TriggerNegotiation(t *testing.T) {
 	s.rekeyThreshold = 51
 	s.negotiationStatus = Confirmed
 
-	if s.triggerNegotiation() {
+	if s.TriggerNegotiation() {
 		t.Error("trigger negotiation unexpectedly failed")
 	}
 	if s.negotiationStatus != Confirmed {
@@ -568,7 +570,7 @@ func TestSession_TriggerNegotiation(t *testing.T) {
 
 	// Test other case: partnerSource sending	confirmation message on unconfirmed session
 	s.negotiationStatus = Unconfirmed
-	if !s.triggerNegotiation() {
+	if !s.TriggerNegotiation() {
 		t.Error("partnerSource negotiation unexpectedly failed")
 	}
 	if s.negotiationStatus != Sending {
@@ -596,7 +598,7 @@ func TestSession_GetTrigger(t *testing.T) {
 }
 
 // Make a default test session with some things populated
-func makeTestSession() (*Session, *context) {
+func makeTestSession() (*Session, *ratchet.context) {
 	grp := getGroup()
 	rng := csprng.NewSystemRNG()
 	partnerPrivKey := dh.GeneratePrivateKey(dh.DefaultPrivateKeyLength,
@@ -617,8 +619,8 @@ func makeTestSession() (*Session, *context) {
 		mySIDHPrivKey, partnerSIDHPubKey)
 
 	// create context objects for general use
-	fps := newFingerprints()
-	ctx := &context{
+	fps := ratchet.newFingerprints()
+	ctx := &ratchet.context{
 		fa:   &fps,
 		grp:  grp,
 		myID: &id.ID{},
@@ -633,8 +635,8 @@ func makeTestSession() (*Session, *context) {
 		mySIDHPrivKey:     mySIDHPrivKey,
 		partnerSIDHPubKey: partnerSIDHPubKey,
 		e2eParams:         params.GetDefaultE2ESessionParams(),
-		relationship: &relationship{
-			manager: &Manager{
+		relationship: &ratchet.relationship{
+			manager: &partner.Manager{
 				ctx:     ctx,
 				kv:      kv,
 				partner: &id.ID{},
diff --git a/storage/e2e/status.go b/e2e/ratchet/partner/session/status.go
similarity index 98%
rename from storage/e2e/status.go
rename to e2e/ratchet/partner/session/status.go
index 63633724d0ad1b3faa2488198fdd4280041b028c..6494e31deafa043fa3bcf433fce5fea80cf772b4 100644
--- a/storage/e2e/status.go
+++ b/e2e/ratchet/partner/session/status.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 import "fmt"
 
diff --git a/storage/e2e/status_test.go b/e2e/ratchet/partner/session/status_test.go
similarity index 98%
rename from storage/e2e/status_test.go
rename to e2e/ratchet/partner/session/status_test.go
index a81894bae53b808ddc632a7881d5945b5b0c2d24..738db5260e63c0396613a3543475e38a4edc8392 100644
--- a/storage/e2e/status_test.go
+++ b/e2e/ratchet/partner/session/status_test.go
@@ -5,7 +5,7 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package session
 
 // Testing file for the status.go functions
 
diff --git a/storage/e2e/store.go b/e2e/ratchet/store.go
similarity index 91%
rename from storage/e2e/store.go
rename to e2e/ratchet/store.go
index 1c9c361106b23062a08c7710afda82889d031d4a..ca16426ed134ab8c67bec6e44bea9058604ce6d2 100644
--- a/storage/e2e/store.go
+++ b/e2e/ratchet/store.go
@@ -5,13 +5,15 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package ratchet
 
 import (
 	"encoding/json"
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/interfaces/params"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/client/storage/versioned"
@@ -39,7 +41,7 @@ const (
 var NoPartnerErrorStr = "No relationship with partner found"
 
 type Store struct {
-	managers map[id.ID]*Manager
+	managers map[id.ID]*partner.Manager
 	mux      sync.RWMutex
 
 	dhPrivateKey *cyclic.Int
@@ -67,7 +69,7 @@ func NewStore(grp *cyclic.Group, kv *versioned.KV, privKey *cyclic.Int,
 	fingerprints := newFingerprints()
 
 	s := &Store{
-		managers: make(map[id.ID]*Manager),
+		managers: make(map[id.ID]*partner.Manager),
 
 		dhPrivateKey: privKey,
 		dhPublicKey:  pubKey,
@@ -117,7 +119,7 @@ func LoadStore(kv *versioned.KV, myID *id.ID, rng *fastRNG.StreamGenerator) (*St
 	}
 
 	s := &Store{
-		managers: make(map[id.ID]*Manager),
+		managers: make(map[id.ID]*partner.Manager),
 
 		fingerprints: &fingerprints,
 
@@ -183,7 +185,7 @@ func (s *Store) AddPartner(partnerID *id.ID, partnerPubKey,
 		return errors.New("Cannot overwrite existing partner")
 	}
 
-	m := newManager(s.context, s.kv, partnerID, myPrivKey, partnerPubKey,
+	m := partner.newManager(s.context, s.kv, partnerID, myPrivKey, partnerPubKey,
 		mySIDHPrivKey, partnerSIDHPubKey,
 		sendParams, receiveParams)
 
@@ -203,7 +205,7 @@ func (s *Store) DeletePartner(partnerId *id.ID) error {
 		return errors.New(NoPartnerErrorStr)
 	}
 
-	if err := clearManager(m, s.kv); err != nil {
+	if err := partner.clearManager(m, s.kv); err != nil {
 		return errors.WithMessagef(err, "Could not remove partner %s from store", partnerId)
 	}
 
@@ -211,7 +213,7 @@ func (s *Store) DeletePartner(partnerId *id.ID) error {
 	return s.save()
 }
 
-func (s *Store) GetPartner(partnerID *id.ID) (*Manager, error) {
+func (s *Store) GetPartner(partnerID *id.ID) (*partner.Manager, error) {
 	s.mux.RLock()
 	defer s.mux.RUnlock()
 
@@ -262,7 +264,7 @@ func (s *Store) GetPartners() []*id.ID {
 }
 
 // PopKey pops a key for use based upon its fingerprint.
-func (s *Store) PopKey(f format.Fingerprint) (*Key, bool) {
+func (s *Store) PopKey(f format.Fingerprint) (*session2.Cypher, bool) {
 	return s.fingerprints.Pop(f)
 }
 
@@ -315,7 +317,7 @@ func (s *Store) unmarshal(b []byte) error {
 		partnerID := (&contacts[i]).DeepCopy()
 		// Load the relationship. The relationship handles adding the fingerprints via the
 		// context object
-		manager, err := loadManager(s.context, s.kv, partnerID)
+		manager, err := partner.loadManager(s.context, s.kv, partnerID)
 		if err != nil {
 			jww.FATAL.Panicf("Failed to load relationship for partner %s: %s",
 				partnerID, err.Error())
@@ -368,20 +370,20 @@ func (s *Store) SetE2ESessionParams(newParams params.E2ESessionParams) {
 }
 
 type fingerprints struct {
-	toKey map[format.Fingerprint]*Key
+	toKey map[format.Fingerprint]*session2.Cypher
 	mux   sync.RWMutex
 }
 
 // newFingerprints creates a new fingerprints with an empty map.
 func newFingerprints() fingerprints {
 	return fingerprints{
-		toKey: make(map[format.Fingerprint]*Key),
+		toKey: make(map[format.Fingerprint]*session2.Cypher),
 	}
 }
 
 // fingerprints adheres to the fingerprintAccess interface.
 
-func (f *fingerprints) add(keys []*Key) {
+func (f *fingerprints) add(keys []*session2.Cypher) {
 	f.mux.Lock()
 	defer f.mux.Unlock()
 
@@ -392,7 +394,7 @@ func (f *fingerprints) add(keys []*Key) {
 	}
 }
 
-func (f *fingerprints) remove(keys []*Key) {
+func (f *fingerprints) remove(keys []*session2.Cypher) {
 	f.mux.Lock()
 	defer f.mux.Unlock()
 
@@ -409,7 +411,7 @@ func (f *fingerprints) Check(fingerprint format.Fingerprint) bool {
 	return ok
 }
 
-func (f *fingerprints) Pop(fingerprint format.Fingerprint) (*Key, bool) {
+func (f *fingerprints) Pop(fingerprint format.Fingerprint) (*session2.Cypher, bool) {
 	f.mux.Lock()
 	defer f.mux.Unlock()
 	key, ok := f.toKey[fingerprint]
diff --git a/storage/e2e/store_test.go b/e2e/ratchet/store_test.go
similarity index 92%
rename from storage/e2e/store_test.go
rename to e2e/ratchet/store_test.go
index 7a209321d8aba398ba33da1442fb85d25eb3e205..feacc60c94494df0d02af10d81153a2d147b7903 100644
--- a/storage/e2e/store_test.go
+++ b/e2e/ratchet/store_test.go
@@ -5,11 +5,14 @@
 // LICENSE file                                                              //
 ///////////////////////////////////////////////////////////////////////////////
 
-package e2e
+package ratchet
 
 import (
 	"bytes"
 	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/e2e/ratchet/session"
 	"gitlab.com/elixxir/client/interfaces/params"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/client/storage/versioned"
@@ -37,7 +40,7 @@ func TestNewStore(t *testing.T) {
 	rng := fastRNG.NewStreamGenerator(12, 3, csprng.NewSystemRNG)
 	e2eP := params.GetDefaultE2ESessionParams()
 	expectedStore := &Store{
-		managers:     make(map[id.ID]*Manager),
+		managers:     make(map[id.ID]*partner.Manager),
 		dhPrivateKey: privKey,
 		dhPublicKey:  diffieHellman.GeneratePublicKey(privKey, grp),
 		grp:          grp,
@@ -107,7 +110,7 @@ func TestStore_AddPartner(t *testing.T) {
 	// initiation of the connection.
 	_, pubSIDHKey := genSidhKeys(rng, sidh.KeyVariantSidhA)
 	privSIDHKey, _ := genSidhKeys(rng, sidh.KeyVariantSidhB)
-	expectedManager := newManager(s.context, s.kv, partnerID,
+	expectedManager := partner.newManager(s.context, s.kv, partnerID,
 		s.dhPrivateKey, pubKey,
 		privSIDHKey, pubSIDHKey,
 		p, p)
@@ -170,7 +173,7 @@ func TestStore_GetPartner(t *testing.T) {
 	p := params.GetDefaultE2ESessionParams()
 	_, pubSIDHKey := genSidhKeys(rng, sidh.KeyVariantSidhA)
 	privSIDHKey, _ := genSidhKeys(rng, sidh.KeyVariantSidhB)
-	expectedManager := newManager(s.context, s.kv, partnerID,
+	expectedManager := partner.newManager(s.context, s.kv, partnerID,
 		s.dhPrivateKey, pubKey, privSIDHKey, pubSIDHKey, p, p)
 	_ = s.AddPartner(partnerID, pubKey, s.dhPrivateKey, pubSIDHKey,
 		privSIDHKey, p, p)
@@ -245,7 +248,7 @@ func TestStore_GetPartnerContact_Error(t *testing.T) {
 // Tests happy path of Store.PopKey.
 func TestStore_PopKey(t *testing.T) {
 	s, _, _ := makeTestStore()
-	se, _ := makeTestSession()
+	se, _ := session.makeTestSession()
 
 	// Pop Key that does not exist
 	fp := format.Fingerprint{0xF, 0x6, 0x2}
@@ -260,7 +263,7 @@ func TestStore_PopKey(t *testing.T) {
 	}
 
 	// Add a Key
-	keys := []*Key{newKey(se, 0), newKey(se, 1), newKey(se, 2)}
+	keys := []*session2.Cypher{session.newKey(se, 0), session.newKey(se, 1), session.newKey(se, 2)}
 	s.add(keys)
 	fp = keys[0].Fingerprint()
 
@@ -279,7 +282,7 @@ func TestStore_PopKey(t *testing.T) {
 // Tests happy path of Store.CheckKey.
 func TestStore_CheckKey(t *testing.T) {
 	s, _, _ := makeTestStore()
-	se, _ := makeTestSession()
+	se, _ := session.makeTestSession()
 
 	// Check for a Key that does not exist
 	fp := format.Fingerprint{0xF, 0x6, 0x2}
@@ -289,7 +292,7 @@ func TestStore_CheckKey(t *testing.T) {
 	}
 
 	// Add Keys
-	keys := []*Key{newKey(se, 0), newKey(se, 1), newKey(se, 2)}
+	keys := []*session2.Cypher{session.newKey(se, 0), session.newKey(se, 1), session.newKey(se, 2)}
 	s.add(keys)
 	fp = keys[0].Fingerprint()
 
@@ -335,7 +338,7 @@ func TestStore_GetGroup(t *testing.T) {
 
 // Tests happy path of newFingerprints.
 func Test_newFingerprints(t *testing.T) {
-	expectedFp := fingerprints{toKey: make(map[format.Fingerprint]*Key)}
+	expectedFp := fingerprints{toKey: make(map[format.Fingerprint]*session2.Cypher)}
 	fp := newFingerprints()
 
 	if !reflect.DeepEqual(&expectedFp, &fp) {
@@ -346,8 +349,8 @@ func Test_newFingerprints(t *testing.T) {
 
 // Tests happy path of fingerprints.add.
 func TestFingerprints_add(t *testing.T) {
-	se, _ := makeTestSession()
-	keys := []*Key{newKey(se, 0), newKey(se, 1), newKey(se, 2)}
+	se, _ := session.makeTestSession()
+	keys := []*session2.Cypher{session.newKey(se, 0), session.newKey(se, 1), session.newKey(se, 2)}
 	fps := newFingerprints()
 	fps.add(keys)
 
@@ -368,8 +371,8 @@ func TestFingerprints_add(t *testing.T) {
 
 // Tests happy path of fingerprints.remove.
 func TestFingerprints_remove(t *testing.T) {
-	se, _ := makeTestSession()
-	keys := []*Key{newKey(se, 0), newKey(se, 1), newKey(se, 2)}
+	se, _ := session.makeTestSession()
+	keys := []*session2.Cypher{session.newKey(se, 0), session.newKey(se, 1), session.newKey(se, 2)}
 	fps := newFingerprints()
 	fps.add(keys)
 	fps.remove(keys)
diff --git a/interfaces/networkManager.go b/interfaces/networkManager.go
index 4914bfb4fa04dd5273ea5bfb775ae1e3450b33ba..b5104d1018151632d4d1ae41767378333990d1bd 100644
--- a/interfaces/networkManager.go
+++ b/interfaces/networkManager.go
@@ -221,17 +221,5 @@ type Preimage [32]byte
 
 type ClientErrorReport func(source, message, trace string)
 
-//type Ratchet interface {
-//	SendE2E(m message.Send, p params.E2E, stop *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error)
-//	SendUnsafe(m message.Send, p params.Unsafe) ([]id.Round, error)
-//	AddPartner(partnerID *id.ID, partnerPubKey,
-//		myPrivKey *cyclic.Int, partnerSIDHPubKey *sidh.PublicKey,
-//		mySIDHPrivKey *sidh.PrivateKey,
-//		sendParams, receiveParams params.E2ESessionParams)
-//	GetPartner(partnerID *id.ID) (*manager, error)
-//	DeletePartner(partnerId *id.ID)
-//	GetAllPartnerIDs() []*id.ID
-//}
-
 //for use in key exchange which needs to be callable inside of network
 ///type SendE2E func(m message.Send, p params.E2E, stop *stoppable.Single) ([]id.Round, e2e.MessageID, time.Time, error)
diff --git a/keyExchange/confirm.go b/keyExchange/confirm.go
index 9e7996ded27d3b79fbed8f3119ecfec0acae8774..3ff7e3183b279de0cebef1071a662f094e29de96 100644
--- a/keyExchange/confirm.go
+++ b/keyExchange/confirm.go
@@ -11,10 +11,10 @@ import (
 	"github.com/golang/protobuf/proto"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/storage/e2e"
 )
 
 func startConfirm(sess *storage.Session, c chan message.Receive,
@@ -69,7 +69,7 @@ func handleConfirm(sess *storage.Session, confirmation message.Receive) {
 	// This is expected sometimes because some errors cases can cause multiple
 	// sends. For example if the sending device runs out of battery after it
 	// sends but before it records the send it will resend on reload
-	if err := confirmedSession.TrySetNegotiationStatus(e2e.Confirmed); err != nil {
+	if err := confirmedSession.TrySetNegotiationStatus(session2.Confirmed); err != nil {
 		jww.WARN.Printf("[REKEY] Failed to set the negotiation status for the "+
 			"confirmation of session %s from partner %s. This is expected in "+
 			"some edge cases but could be a sign of an issue if it persists: %s",
@@ -80,17 +80,17 @@ func handleConfirm(sess *storage.Session, confirmation message.Receive) {
 		"%s from partner %s.", confirmedSession, partner.GetPartnerID())
 }
 
-func unmarshalConfirm(payload []byte) (e2e.SessionID, error) {
+func unmarshalConfirm(payload []byte) (session2.SessionID, error) {
 
 	msg := &RekeyConfirm{}
 	if err := proto.Unmarshal(payload, msg); err != nil {
-		return e2e.SessionID{}, errors.Errorf("Failed to "+
+		return session2.SessionID{}, errors.Errorf("Failed to "+
 			"unmarshal payload: %s", err)
 	}
 
-	confirmedSessionID := e2e.SessionID{}
+	confirmedSessionID := session2.SessionID{}
 	if err := confirmedSessionID.Unmarshal(msg.SessionID); err != nil {
-		return e2e.SessionID{}, errors.Errorf("Failed to unmarshal"+
+		return session2.SessionID{}, errors.Errorf("Failed to unmarshal"+
 			" sessionID: %s", err)
 	}
 
diff --git a/keyExchange/confirm_test.go b/keyExchange/confirm_test.go
index 3dd8312ec791dfce8f70b195f1e80a865d4759c3..87c453093c6c0cdb0fb3d6d0d378441fbdf753bf 100644
--- a/keyExchange/confirm_test.go
+++ b/keyExchange/confirm_test.go
@@ -10,9 +10,9 @@ package keyExchange
 import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/interfaces/params"
-	"gitlab.com/elixxir/client/storage/e2e"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/xx_network/primitives/id"
 	"gitlab.com/xx_network/primitives/netTime"
@@ -94,7 +94,7 @@ func TestHandleConfirm(t *testing.T) {
 
 	// Check that the session is in the proper status
 	newSession := receivedManager.GetSendSession(sessionID)
-	if newSession.NegotiationStatus() != e2e.Confirmed {
+	if newSession.NegotiationStatus() != session2.Confirmed {
 		t.Errorf("Session not in confirmed status!"+
 			"\n\tExpected: Confirmed"+
 			"\n\tReceived: %s", confirmedSession.NegotiationStatus())
diff --git a/keyExchange/exchange_test.go b/keyExchange/exchange_test.go
index 7136ea3dc36a23256af933b1f2030567393b13cb..04d6c4ec205d5396fab1e29dd5b64540425fa547 100644
--- a/keyExchange/exchange_test.go
+++ b/keyExchange/exchange_test.go
@@ -11,11 +11,11 @@ import (
 	"fmt"
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/interfaces"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/storage/e2e"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/client/switchboard"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
@@ -124,14 +124,14 @@ func TestFullExchange(t *testing.T) {
 	confirmedSession := receivedManager.GetSendSession(oldSessionID)
 
 	// Generate the new session ID based off of Bob's new keys
-	baseKey := e2e.GenerateE2ESessionBaseKey(alicePrivKey, newBobPubKey,
+	baseKey := session2.GenerateE2ESessionBaseKey(alicePrivKey, newBobPubKey,
 		genericGroup, aliceSIDHPrivKey, newBobSIDHPubKey)
-	newSessionID := e2e.GetSessionIDFromBaseKeyForTesting(baseKey, t)
+	newSessionID := session2.GetSessionIDFromBaseKeyForTesting(baseKey, t)
 
 	// Check that the Alice's session for Bob is in the proper status
 	newSession := receivedManager.GetReceiveSession(newSessionID)
 	fmt.Printf("newSession: %v\n", newSession)
-	if newSession == nil || newSession.NegotiationStatus() != e2e.Confirmed {
+	if newSession == nil || newSession.NegotiationStatus() != session2.Confirmed {
 		t.Errorf("Session not in confirmed status!"+
 			"\n\tExpected: Confirmed"+
 			"\n\tReceived: %s", confirmedSession.NegotiationStatus())
diff --git a/keyExchange/rekey.go b/keyExchange/rekey.go
index bf5d77803692f09e4327ca4193a9b0e0cd7f585e..e76f54652cf58f9f1e9b0c0b5975c9d1eceb7a7d 100644
--- a/keyExchange/rekey.go
+++ b/keyExchange/rekey.go
@@ -12,6 +12,8 @@ import (
 	"github.com/golang/protobuf/proto"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	session3 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/event"
 	"gitlab.com/elixxir/client/interfaces"
 	"gitlab.com/elixxir/client/interfaces/message"
@@ -19,7 +21,6 @@ import (
 	network2 "gitlab.com/elixxir/client/network"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/storage/e2e"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/comms/network"
 	ds "gitlab.com/elixxir/comms/network/dataStructures"
@@ -30,7 +31,7 @@ import (
 
 func CheckKeyExchanges(instance *network.Instance, sendE2E interfaces.SendE2E,
 	events event.Manager, sess *storage.Session,
-	manager *e2e.Manager, sendTimeout time.Duration,
+	manager *partner.Manager, sendTimeout time.Duration,
 	stop *stoppable.Single) {
 	sessions := manager.TriggerNegotiations()
 	for _, session := range sessions {
@@ -45,23 +46,23 @@ func CheckKeyExchanges(instance *network.Instance, sendE2E interfaces.SendE2E,
 // session while the latter on an extant session
 func trigger(instance *network.Instance, sendE2E interfaces.SendE2E,
 	events event.Manager, sess *storage.Session,
-	manager *e2e.Manager, session *e2e.Session,
+	manager *partner.Manager, session *session3.Session,
 	sendTimeout time.Duration, stop *stoppable.Single) {
-	var negotiatingSession *e2e.Session
+	var negotiatingSession *session3.Session
 	jww.INFO.Printf("[REKEY] Negotiation triggered for session %s with "+
 		"status: %s", session, session.NegotiationStatus())
 	switch session.NegotiationStatus() {
 	// If the passed session is triggering a negotiation on a new session to
 	// replace itself, then create the session
-	case e2e.NewSessionTriggered:
+	case session3.NewSessionTriggered:
 		//create the session, pass a nil private key to generate a new one
 		negotiatingSession = manager.NewSendSession(nil, nil,
 			sess.E2e().GetE2ESessionParams())
 		//move the state of the triggering session forward
-		session.SetNegotiationStatus(e2e.NewSessionCreated)
+		session.SetNegotiationStatus(session3.NewSessionCreated)
 
 	// If the session is set to send a negotiation
-	case e2e.Sending:
+	case session3.Sending:
 		negotiatingSession = session
 	default:
 		jww.FATAL.Panicf("[REKEY] Session %s provided invalid e2e "+
@@ -83,7 +84,7 @@ func trigger(instance *network.Instance, sendE2E interfaces.SendE2E,
 }
 
 func negotiate(instance *network.Instance, sendE2E interfaces.SendE2E,
-	sess *storage.Session, session *e2e.Session, sendTimeout time.Duration,
+	sess *storage.Session, session *session3.Session, sendTimeout time.Duration,
 	rekeyPreimage []byte, stop *stoppable.Single) error {
 	e2eStore := sess.E2e()
 
@@ -152,7 +153,7 @@ func negotiate(instance *network.Instance, sendE2E interfaces.SendE2E,
 	// transmit, the partner cannot read the result. Log the error and set
 	// the session as unconfirmed so it will re-trigger the negotiation
 	if !success {
-		session.SetNegotiationStatus(e2e.Unconfirmed)
+		session.SetNegotiationStatus(session3.Unconfirmed)
 		return errors.Errorf("[REKEY] Key Negotiation rekey for %s failed to "+
 			"transmit %v/%v paritions: %v round failures, %v timeouts, msgID: %s",
 			session, numRoundFail+numTimeOut, len(rounds), numRoundFail,
@@ -163,9 +164,9 @@ func negotiate(instance *network.Instance, sendE2E interfaces.SendE2E,
 	// in the session and the log
 	jww.INFO.Printf("[REKEY] Key Negotiation rekey transmission for %s, msgID %s successful",
 		session, msgID)
-	err = session.TrySetNegotiationStatus(e2e.Sent)
+	err = session.TrySetNegotiationStatus(session3.Sent)
 	if err != nil {
-		if session.NegotiationStatus() == e2e.NewSessionTriggered {
+		if session.NegotiationStatus() == session3.NewSessionTriggered {
 			msg := fmt.Sprintf("All channels exhausted for %s, "+
 				"rekey impossible.", session)
 			return errors.WithMessage(err, msg)
diff --git a/keyExchange/trigger.go b/keyExchange/trigger.go
index 984fc3306400da69c38f2005b4e1695e153c6563..85e68e48b2493e1131c5d1d09043a34f56b8770e 100644
--- a/keyExchange/trigger.go
+++ b/keyExchange/trigger.go
@@ -13,13 +13,13 @@ import (
 	"github.com/golang/protobuf/proto"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/interfaces"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/network"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/storage/e2e"
 	util "gitlab.com/elixxir/client/storage/utility"
 	ds "gitlab.com/elixxir/comms/network/dataStructures"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -168,26 +168,26 @@ func handleTrigger(sess *storage.Session, net interfaces.NetworkManager,
 	return nil
 }
 
-func unmarshalSource(grp *cyclic.Group, payload []byte) (e2e.SessionID,
+func unmarshalSource(grp *cyclic.Group, payload []byte) (session2.SessionID,
 	*cyclic.Int, *sidh.PublicKey, error) {
 
 	msg := &RekeyTrigger{}
 	if err := proto.Unmarshal(payload, msg); err != nil {
-		return e2e.SessionID{}, nil, nil, errors.Errorf(
+		return session2.SessionID{}, nil, nil, errors.Errorf(
 			"Failed to unmarshal payload: %s", err)
 	}
 
-	oldSessionID := e2e.SessionID{}
+	oldSessionID := session2.SessionID{}
 
 	if err := oldSessionID.Unmarshal(msg.SessionID); err != nil {
-		return e2e.SessionID{}, nil, nil, errors.Errorf(
+		return session2.SessionID{}, nil, nil, errors.Errorf(
 			"Failed to unmarshal sessionID: %s", err)
 	}
 
 	// checking it is inside the group is necessary because otherwise the
 	// creation of the cyclic int will crash below
 	if !grp.BytesInside(msg.PublicKey) {
-		return e2e.SessionID{}, nil, nil, errors.Errorf(
+		return session2.SessionID{}, nil, nil, errors.Errorf(
 			"Public key not in e2e group; PublicKey %v",
 			msg.PublicKey)
 	}
diff --git a/keyExchange/trigger_test.go b/keyExchange/trigger_test.go
index 610428b2ce0ed3c84a2ececca56827b60c9b476e..6391fbab07cf54391c346f41162c42b556964583 100644
--- a/keyExchange/trigger_test.go
+++ b/keyExchange/trigger_test.go
@@ -9,10 +9,10 @@ package keyExchange
 
 import (
 	"github.com/cloudflare/circl/dh/sidh"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/stoppable"
-	"gitlab.com/elixxir/client/storage/e2e"
 	util "gitlab.com/elixxir/client/storage/utility"
 	dh "gitlab.com/elixxir/crypto/diffieHellman"
 	"gitlab.com/xx_network/crypto/csprng"
@@ -109,9 +109,9 @@ func TestHandleTrigger(t *testing.T) {
 	}
 
 	// Generate the new session ID based off of Bob's new keys
-	baseKey := e2e.GenerateE2ESessionBaseKey(alicePrivKey, newBobPubKey,
+	baseKey := session2.GenerateE2ESessionBaseKey(alicePrivKey, newBobPubKey,
 		genericGroup, aliceSIDHPrivKey, newBobSIDHPubKey)
-	newSessionID := e2e.GetSessionIDFromBaseKeyForTesting(baseKey, t)
+	newSessionID := session2.GetSessionIDFromBaseKeyForTesting(baseKey, t)
 
 	// Check that this new session ID is now in the manager
 	newSession := receivedManager.GetReceiveSession(newSessionID)
@@ -124,7 +124,7 @@ func TestHandleTrigger(t *testing.T) {
 	unknownPubliceKey := dh.GeneratePublicKey(unknownPrivateKey, genericGroup)
 
 	// Generate a new session ID based off of these unrecognized keys
-	badSessionID := e2e.GetSessionIDFromBaseKeyForTesting(unknownPubliceKey, t)
+	badSessionID := session2.GetSessionIDFromBaseKeyForTesting(unknownPubliceKey, t)
 
 	// Check that this session with unrecognized keys is not valid
 	badSession := receivedManager.GetReceiveSession(badSessionID)
diff --git a/keyExchange/utils_test.go b/keyExchange/utils_test.go
index ef27ae79eb04cd7917cb62f557c093351a674a01..ed32032b4320569573019a3b74a6af65c218c652 100644
--- a/keyExchange/utils_test.go
+++ b/keyExchange/utils_test.go
@@ -11,6 +11,7 @@ import (
 	"github.com/cloudflare/circl/dh/sidh"
 	"github.com/golang/protobuf/proto"
 	jww "github.com/spf13/jwalterweatherman"
+	session2 "gitlab.com/elixxir/client/e2e/ratchet/partner/session"
 	"gitlab.com/elixxir/client/event"
 	"gitlab.com/elixxir/client/interfaces"
 	"gitlab.com/elixxir/client/interfaces/message"
@@ -18,7 +19,6 @@ import (
 	"gitlab.com/elixxir/client/network/gateway"
 	"gitlab.com/elixxir/client/stoppable"
 	"gitlab.com/elixxir/client/storage"
-	"gitlab.com/elixxir/client/storage/e2e"
 	util "gitlab.com/elixxir/client/storage/utility"
 	"gitlab.com/elixxir/client/switchboard"
 	"gitlab.com/elixxir/comms/network"
@@ -40,14 +40,14 @@ import (
 // Generate partner ID for two people, used for smoke tests
 func GeneratePartnerID(aliceKey, bobKey *cyclic.Int,
 	group *cyclic.Group, alicePrivKey *sidh.PrivateKey,
-	bobPubKey *sidh.PublicKey) e2e.SessionID {
-	baseKey := e2e.GenerateE2ESessionBaseKey(aliceKey, bobKey, group,
+	bobPubKey *sidh.PublicKey) session2.SessionID {
+	baseKey := session2.GenerateE2ESessionBaseKey(aliceKey, bobKey, group,
 		alicePrivKey, bobPubKey)
 
 	h, _ := hash.NewCMixHash()
 	h.Write(baseKey.Bytes())
 
-	sid := e2e.SessionID{}
+	sid := session2.SessionID{}
 
 	copy(sid[:], h.Sum(nil))
 
diff --git a/network/interface.go b/network/interface.go
index 4a11335e4742a069dccf88730b1571c4e2acc231..1d23002387d6c993c2d65bb153031132d99cd0cb 100644
--- a/network/interface.go
+++ b/network/interface.go
@@ -97,15 +97,21 @@ type Manager interface {
 
 	// AddFingerprint - Adds a fingerprint which will be handled by a
 	// specific processor for messages received by the given identity
+	// If a nil identity is passed, it will automatically use the default
+	// identity in the session
 	AddFingerprint(identity *id.ID, fingerprint format.Fingerprint,
 		mp message.Processor) error
 
 	// DeleteFingerprint deletes a single fingerprint associated with the given
 	// identity if it exists
+	// If a nil identity is passed, it will automatically use the default
+	// identity in the session
 	DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint)
 
 	// DeleteClientFingerprints deletes al fingerprint associated with the given
 	// identity if it exists
+	// A sepecific identity must be supplied, a nil identity will result in a
+	// panic
 	DeleteClientFingerprints(identity *id.ID)
 
 	/* Service - predefined hash based tags appended to all cMix messages
diff --git a/network/manager.go b/network/manager.go
index d7ccd6372a8d9c433c81c351ed656df89d4966e8..555b60105aa76c109faed58c1dd073c52bea61f9 100644
--- a/network/manager.go
+++ b/network/manager.go
@@ -149,7 +149,8 @@ func NewManager(params Params, comms *client.Comms, session storage.Session,
 	m.Retriever = historical.NewRetriever(params.Historical, comms, m.Sender, events)
 
 	//Set up Message Handler
-	m.Handler = message.NewHandler(params.Message, m.session.GetKV(), m.events)
+	m.Handler = message.NewHandler(params.Message, m.session.GetKV(), m.events,
+		m.session.GetReceptionID())
 
 	//set up round handler
 	m.Pickup = rounds.NewPickup(params.Rounds, m.Handler.GetMessageReceptionChannel(),
diff --git a/network/message/fingerprints.go b/network/message/fingerprints.go
index d79f865615ead3490c5eb373f5fc72a9bd3bea64..7a734f2f43a285b86e56694623afa37a9343af79 100644
--- a/network/message/fingerprints.go
+++ b/network/message/fingerprints.go
@@ -18,14 +18,16 @@ import (
 // FingerprintsManager is a thread-safe map, mapping format.Fingerprint's to a
 // Handler object.
 type FingerprintsManager struct {
-	fpMap map[id.ID]map[format.Fingerprint]Processor
+	fpMap      map[id.ID]map[format.Fingerprint]Processor
+	standardID *id.ID
 	sync.Mutex
 }
 
 // newFingerprints is a constructor function for the fingerprints tracker.
-func newFingerprints() *FingerprintsManager {
+func newFingerprints(standardID *id.ID) *FingerprintsManager {
 	return &FingerprintsManager{
-		fpMap: make(map[id.ID]map[format.Fingerprint]Processor),
+		fpMap:      make(map[id.ID]map[format.Fingerprint]Processor),
+		standardID: standardID,
 	}
 }
 
@@ -56,11 +58,17 @@ func (f *FingerprintsManager) pop(clientID *id.ID,
 // AddFingerprint maps the given fingerprint key to the handler value. If there
 // is already an entry for this fingerprint, the method returns with no write
 // operation.
+// If a nil identity is passed, it will automatically use the default
+// identity in the session
 func (f *FingerprintsManager) AddFingerprint(clientID *id.ID,
 	fingerprint format.Fingerprint, mp Processor) error {
 	f.Lock()
 	defer f.Unlock()
 
+	if clientID == nil {
+		clientID = f.standardID
+	}
+
 	cid := *clientID
 
 	if _, exists := f.fpMap[cid]; !exists {
@@ -83,6 +91,10 @@ func (f *FingerprintsManager) DeleteFingerprint(clientID *id.ID,
 	f.Lock()
 	defer f.Unlock()
 
+	if clientID == nil {
+		clientID = f.standardID
+	}
+
 	cid := *clientID
 
 	if _, exists := f.fpMap[cid]; exists {
diff --git a/network/message/fingerprints_test.go b/network/message/fingerprints_test.go
index 66784d284c7e9456699eaa659144b5a6a3e78d14..873ef57a2f9c206f641b28f28f052b302f6fe410 100644
--- a/network/message/fingerprints_test.go
+++ b/network/message/fingerprints_test.go
@@ -24,7 +24,7 @@ func Test_newFingerprints(t *testing.T) {
 		fpMap: make(map[id.ID]map[format.Fingerprint]Processor),
 	}
 
-	received := newFingerprints()
+	received := newFingerprints(&id.ID{})
 	if !reflect.DeepEqual(expected, received) {
 		t.Fatalf("New FingerprintsManager did not match expected."+
 			"\nexpected: %+v\nreceived: %+v", expected, received)
@@ -34,7 +34,7 @@ func Test_newFingerprints(t *testing.T) {
 // Unit test.
 func TestFingerprintsManager_pop(t *testing.T) {
 	// Construct fingerprint map
-	fpTracker := newFingerprints()
+	fpTracker := newFingerprints(&id.ID{})
 
 	// Construct fingerprint and handler values
 	cid := id.NewIdFromString("clientID", id.User, t)
@@ -66,7 +66,7 @@ func TestFingerprintsManager_pop(t *testing.T) {
 // Unit test.
 func TestFingerprintsManager_AddFingerprint(t *testing.T) {
 	// Construct fingerprint map
-	fpTracker := newFingerprints()
+	fpTracker := newFingerprints(&id.ID{})
 
 	// Construct fingerprint and handler values
 	cid := id.NewIdFromString("clientID", id.User, t)
@@ -97,7 +97,7 @@ func TestFingerprintsManager_AddFingerprint(t *testing.T) {
 func TestFingerprintsManager_DeleteFingerprint(t *testing.T) {
 
 	// Construct fingerprint map
-	fpTracker := newFingerprints()
+	fpTracker := newFingerprints(&id.ID{})
 
 	// Construct fingerprint and handler values
 	cid := id.NewIdFromString("clientID", id.User, t)
@@ -123,7 +123,7 @@ func TestFingerprintsManager_DeleteFingerprint(t *testing.T) {
 // Unit test.
 func TestFingerprintsManager_DeleteClientFingerprints(t *testing.T) {
 	// Construct fingerprints map
-	fpTracker := newFingerprints()
+	fpTracker := newFingerprints(&id.ID{})
 
 	// Construct slices of fingerprints and processors
 	numTests := 100
diff --git a/network/message/handler.go b/network/message/handler.go
index 75728fc6a22b5b73e15f723af47051e2ef0f1bd0..687f68544c3413f452e9deda1b77d18515995f72 100644
--- a/network/message/handler.go
+++ b/network/message/handler.go
@@ -74,13 +74,13 @@ func (p *handler) handleMessage(ecrMsg format.Message, bundle Bundle) bool {
 		return true
 	}
 
-	triggers, exists := p.get(
+	services, exists := p.get(
 		identity.Source, ecrMsg.GetSIH(), ecrMsg.GetContents())
 	if exists {
-		for _, t := range triggers {
+		for _, t := range services {
 			go t.Process(ecrMsg, identity, round)
 		}
-		if len(triggers) == 0 {
+		if len(services) == 0 {
 			jww.ERROR.Printf("empty service list for %s", ecrMsg.GetSIH())
 		}
 		return true
diff --git a/network/message/pickup.go b/network/message/pickup.go
index 4119e720465d4a9891a89b98cf3e13b7e6bb615a..acba1c0382c1190c8f7524dbdba40852dfa7e415 100644
--- a/network/message/pickup.go
+++ b/network/message/pickup.go
@@ -53,7 +53,8 @@ type handler struct {
 	ServicesManager
 }
 
-func NewHandler(param Params, kv *versioned.KV, events event.Manager) Handler {
+func NewHandler(param Params, kv *versioned.KV, events event.Manager,
+	standardID *id.ID) Handler {
 
 	garbled, err := NewOrLoadMeteredCmixMessageBuffer(kv, inProcessKey)
 	if err != nil {
@@ -69,7 +70,7 @@ func NewHandler(param Params, kv *versioned.KV, events event.Manager) Handler {
 		events:           events,
 	}
 
-	m.FingerprintsManager = *newFingerprints()
+	m.FingerprintsManager = *newFingerprints(standardID)
 	m.ServicesManager = *NewServices()
 	return &m
 }
diff --git a/network/nodes/mixCypher.go b/network/nodes/mixCypher.go
index c94b8007394c388c0423cada55cf7fdb7e0fbc2e..730212defe1ac6f8a2104ba0a1bea1185ddc2c0d 100644
--- a/network/nodes/mixCypher.go
+++ b/network/nodes/mixCypher.go
@@ -19,7 +19,7 @@ import (
 
 type MixCypher interface {
 	Encrypt(msg format.Message, salt []byte, roundID id.Round) (format.Message, [][]byte)
-	MakeClientGatewayKey(salt, digest []byte) []byte
+	MakeClientGatewayAuthMAC(salt, digest []byte) []byte
 }
 
 type mixCypher struct {
@@ -56,7 +56,7 @@ func (mc *mixCypher) Encrypt(msg format.Message,
 	return ecrMsg, KMAC
 }
 
-func (mc *mixCypher) MakeClientGatewayKey(salt, digest []byte) []byte {
+func (mc *mixCypher) MakeClientGatewayAuthMAC(salt, digest []byte) []byte {
 	clientGatewayKey := cmix.GenerateClientGatewayKey(mc.keys[0].k)
 	h, _ := hash.NewCMixHash()
 	h.Write(clientGatewayKey)
diff --git a/network/sendCmixUtils.go b/network/sendCmixUtils.go
index 18c629e7fde1ab59cb146319f3e566e68655ddb1..0d0f89094b005d60529b81b5caf8254b0590cad1 100644
--- a/network/sendCmixUtils.go
+++ b/network/sendCmixUtils.go
@@ -160,7 +160,7 @@ func buildSlotMessage(msg format.Message, recipient *id.ID, target *id.ID,
 	}
 
 	// Add the mac proving ownership
-	slot.MAC = mixCrypt.MakeClientGatewayKey(salt,
+	slot.MAC = mixCrypt.MakeClientGatewayAuthMAC(salt,
 		network.GenerateSlotDigest(slot))
 
 	return slot, encMsg, ephID, nil