diff --git a/catalog/messageTypes.go b/catalog/messageTypes.go
index 969e6c703d1f56ab5db32bcbebfed0acf0d74c42..3f33fe648995ca275177d35f7fd32961bdb5b01e 100644
--- a/catalog/messageTypes.go
+++ b/catalog/messageTypes.go
@@ -42,4 +42,9 @@ const (
 	// EndFileTransfer is sent once all file parts have been transmitted to
 	// inform the receiver that the file transfer has ended.
 	EndFileTransfer = 51
+
+	// ConnectionAuthenticationRequest is sent by the recipient
+	// of an authenticated connection request
+	// (see the connect/ package)
+	ConnectionAuthenticationRequest = 60
 )
diff --git a/connect/authenticated.go b/connect/authenticated.go
new file mode 100644
index 0000000000000000000000000000000000000000..518bbc2eb482f12c23005071e4e81f42c47caf38
--- /dev/null
+++ b/connect/authenticated.go
@@ -0,0 +1,219 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"github.com/pkg/errors"
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/cmix"
+	clientE2e "gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/crypto/contact"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/crypto/signature/rsa"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/netTime"
+	"sync"
+	"time"
+)
+
+// Constant error messages
+const (
+	roundTrackingTimeoutErr    = "timed out waiting for round results"
+	notAllRoundsSucceededErr   = "not all rounds succeeded"
+	failedToCloseConnectionErr = "failed to close connection with %s " +
+		"after error %v: %+v"
+)
+
+// AuthenticatedConnection is a connect.Connection interface that
+// has the receiver authenticating their identity back to the
+// initiator.
+type AuthenticatedConnection interface {
+	// Connection is the base Connect API. This allows
+	// sending and listening to the partner
+	Connection
+
+	// IsAuthenticated is a function which returns whether the
+	// authenticated connection has been completely established.
+	IsAuthenticated() bool
+}
+
+// AuthenticatedCallback is the callback format required to retrieve
+// new AuthenticatedConnection objects as they are established.
+type AuthenticatedCallback func(connection AuthenticatedConnection)
+
+// ConnectWithAuthentication is called by the client, ie the one establishing
+// connection with the server. Once a connect.Connection has been established
+// with the server and then authenticate their identity to the server.
+func ConnectWithAuthentication(recipient contact.Contact, myId *id.ID,
+	salt []byte, myRsaPrivKey *rsa.PrivateKey, myDhPrivKey *cyclic.Int,
+	rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client,
+	p Params) (AuthenticatedConnection, error) {
+
+	// Track the time since we started to attempt to establish a connection
+	timeStart := netTime.Now()
+
+	// Establish a connection with the server
+	conn, err := Connect(recipient, myId, myDhPrivKey, rng, grp, net, p)
+	if err != nil {
+		return nil, errors.Errorf("failed to establish connection "+
+			"with recipient %s: %+v", recipient.ID, err)
+	}
+
+	// Build the authenticated connection and return
+	return connectWithAuthentication(conn, timeStart, recipient, salt, myRsaPrivKey,
+		rng, net, p)
+}
+
+// connectWithAuthentication builds and sends an IdentityAuthentication to
+// the server. This will wait until the round it sends on completes or a
+// timeout occurs.
+func connectWithAuthentication(conn Connection, timeStart time.Time,
+	recipient contact.Contact, salt []byte, myRsaPrivKey *rsa.PrivateKey,
+	rng *fastRNG.StreamGenerator,
+	net cmix.Client, p Params) (AuthenticatedConnection, error) {
+	// Construct message to prove your identity to the server
+	payload, err := buildClientAuthRequest(conn.GetPartner(), rng,
+		myRsaPrivKey, salt)
+	if err != nil {
+		// Close connection on an error
+		errClose := conn.Close()
+		if errClose != nil {
+			return nil, errors.Errorf(
+				failedToCloseConnectionErr,
+				recipient.ID, err, errClose)
+		}
+		return nil, errors.WithMessagef(err, "failed to construct client "+
+			"authentication message")
+	}
+
+	// Send message to server
+	rids, _, _, err := conn.SendE2E(catalog.ConnectionAuthenticationRequest,
+		payload, clientE2e.GetDefaultParams())
+	if err != nil {
+		// Close connection on an error
+		errClose := conn.Close()
+		if errClose != nil {
+			return nil, errors.Errorf(
+				failedToCloseConnectionErr,
+				recipient.ID, err, errClose)
+		}
+		return nil, errors.WithMessagef(err, "failed to send client "+
+			"authentication message")
+	}
+
+	// Determine that the message is properly sent by tracking the success
+	// of the round(s)
+	roundErr := make(chan error, 1)
+	roundCb := cmix.RoundEventCallback(func(allRoundsSucceeded,
+		timedOut bool, rounds map[id.Round]cmix.RoundResult) {
+		// Check for failures while tracking rounds
+		if timedOut || !allRoundsSucceeded {
+			if timedOut {
+				roundErr <- errors.New(roundTrackingTimeoutErr)
+			} else {
+				// If we did not time out, then not all rounds succeeded
+				roundErr <- errors.New(notAllRoundsSucceededErr)
+			}
+			return
+		}
+
+		// If no errors occurred, signal so; an authenticated channel may
+		// be constructed now
+		roundErr <- nil
+	})
+
+	// Find the remaining time in the timeout since we first sent the message
+	remainingTime := p.Timeout - netTime.Since(timeStart)
+
+	// Track the result of the round(s) we sent the
+	// identity authentication message on
+	err = net.GetRoundResults(remainingTime,
+		roundCb, rids...)
+	if err != nil {
+		return nil, errors.Errorf("could not track rounds for successful " +
+			"identity confirmation message delivery")
+	}
+	// Block waiting for confirmation of the round(s) success (or timeout
+	jww.DEBUG.Printf("AuthenticatedConnection waiting for authenticated "+
+		"connection with %s to be established...", recipient.ID.String())
+	// Wait for the round callback to send a round error
+	err = <-roundErr
+	if err != nil {
+		// Close connection on an error
+		errClose := conn.Close()
+		if errClose != nil {
+			return nil, errors.Errorf(
+				failedToCloseConnectionErr,
+				recipient.ID, err, errClose)
+		}
+
+		return nil, errors.Errorf("failed to confirm if identity "+
+			"authentication message was sent to %s: %v", recipient.ID, err)
+	}
+
+	// If channel received no error, construct and return the
+	// authenticated connection
+	authConn := buildAuthenticatedConnection(conn)
+	authConn.setAuthenticated()
+	return authConn, nil
+}
+
+// StartAuthenticatedServer is called by the receiver of an
+// authenticated connection request. Calling this will indicate that they
+// will handle authenticated requests and verify the client's attempt to
+// authenticate themselves. An established AuthenticatedConnection will
+// be passed via the callback.
+func StartAuthenticatedServer(cb AuthenticatedCallback,
+	myId *id.ID, privKey *cyclic.Int,
+	rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client,
+	p Params) error {
+
+	// Register the waiter for a connection establishment
+	connCb := Callback(func(connection Connection) {
+		// Upon establishing a connection, register a listener for the
+		// client's identity proof. If an identity authentication
+		// message is received and validated, an authenticated connection will
+		// be passed along via the AuthenticatedCallback
+		connection.RegisterListener(catalog.ConnectionAuthenticationRequest,
+			buildAuthConfirmationHandler(cb, connection))
+	})
+	return StartServer(connCb, myId, privKey, rng, grp,
+		net, p)
+}
+
+// authenticatedHandler provides an implementation for the
+// AuthenticatedConnection interface.
+type authenticatedHandler struct {
+	Connection
+	isAuthenticated bool
+	authMux         sync.Mutex
+}
+
+// buildAuthenticatedConnection assembles an AuthenticatedConnection object.
+func buildAuthenticatedConnection(conn Connection) *authenticatedHandler {
+	return &authenticatedHandler{
+		Connection:      conn,
+		isAuthenticated: false,
+	}
+}
+
+// IsAuthenticated returns whether the AuthenticatedConnection has completed
+// the authentication process.
+func (h *authenticatedHandler) IsAuthenticated() bool {
+	return h.isAuthenticated
+}
+
+// setAuthenticated is a helper function which sets the
+// AuthenticatedConnection as authenticated.
+func (h *authenticatedHandler) setAuthenticated() {
+	h.authMux.Lock()
+	defer h.authMux.Unlock()
+	h.isAuthenticated = true
+}
diff --git a/connect/authenticated.pb.go b/connect/authenticated.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..a12961650fe8a763a5b07be50163f4b4ef496acc
--- /dev/null
+++ b/connect/authenticated.pb.go
@@ -0,0 +1,100 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: connect/authenticated/authenticated.proto
+
+package connect // import "gitlab.com/elixxir/client/connect/authenticated"
+
+import proto "github.com/golang/protobuf/proto"
+import fmt "fmt"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.ProtoPackageIsVersion2 // please upgrade the proto package
+
+// Sent by the receiver of the authenticated connection request.
+type IdentityAuthentication struct {
+	Signature []byte `protobuf:"bytes,1,opt,name=Signature,proto3" json:"Signature,omitempty"`
+	// established between the two partners
+	RsaPubKey []byte `protobuf:"bytes,2,opt,name=RsaPubKey,proto3" json:"RsaPubKey,omitempty"`
+	// PEM-encoded
+	Salt                 []byte   `protobuf:"bytes,3,opt,name=Salt,proto3" json:"Salt,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *IdentityAuthentication) Reset()         { *m = IdentityAuthentication{} }
+func (m *IdentityAuthentication) String() string { return proto.CompactTextString(m) }
+func (*IdentityAuthentication) ProtoMessage()    {}
+func (*IdentityAuthentication) Descriptor() ([]byte, []int) {
+	return fileDescriptor_authenticated_9ed9358e4abe7a3a, []int{0}
+}
+func (m *IdentityAuthentication) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_IdentityAuthentication.Unmarshal(m, b)
+}
+func (m *IdentityAuthentication) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_IdentityAuthentication.Marshal(b, m, deterministic)
+}
+func (dst *IdentityAuthentication) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_IdentityAuthentication.Merge(dst, src)
+}
+func (m *IdentityAuthentication) XXX_Size() int {
+	return xxx_messageInfo_IdentityAuthentication.Size(m)
+}
+func (m *IdentityAuthentication) XXX_DiscardUnknown() {
+	xxx_messageInfo_IdentityAuthentication.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_IdentityAuthentication proto.InternalMessageInfo
+
+func (m *IdentityAuthentication) GetSignature() []byte {
+	if m != nil {
+		return m.Signature
+	}
+	return nil
+}
+
+func (m *IdentityAuthentication) GetRsaPubKey() []byte {
+	if m != nil {
+		return m.RsaPubKey
+	}
+	return nil
+}
+
+func (m *IdentityAuthentication) GetSalt() []byte {
+	if m != nil {
+		return m.Salt
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*IdentityAuthentication)(nil), "authenticatedConnectionMessages.IdentityAuthentication")
+}
+
+func init() {
+	proto.RegisterFile("connect/authenticated/authenticated.proto", fileDescriptor_authenticated_9ed9358e4abe7a3a)
+}
+
+var fileDescriptor_authenticated_9ed9358e4abe7a3a = []byte{
+	// 180 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xd2, 0x4d, 0xce, 0xcf, 0xcb,
+	0x4b, 0x4d, 0x2e, 0xc9, 0xcc, 0xcf, 0x2b, 0xd6, 0x4f, 0x2c, 0x2d, 0xc9, 0x48, 0xcd, 0x2b, 0xc9,
+	0x4c, 0x4e, 0x2c, 0x49, 0x4d, 0x41, 0xe5, 0xe9, 0x15, 0x14, 0xe5, 0x97, 0xe4, 0x0b, 0xc9, 0xa3,
+	0x08, 0x3a, 0xc3, 0xf5, 0xfa, 0xa6, 0x16, 0x17, 0x27, 0xa6, 0xa7, 0x16, 0x2b, 0x65, 0x70, 0x89,
+	0x79, 0xa6, 0x80, 0x14, 0x94, 0x54, 0x3a, 0x22, 0x94, 0x66, 0xe6, 0xe7, 0x09, 0xc9, 0x70, 0x71,
+	0x06, 0x67, 0xa6, 0xe7, 0x25, 0x96, 0x94, 0x16, 0xa5, 0x4a, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04,
+	0x21, 0x04, 0x40, 0xb2, 0x41, 0xc5, 0x89, 0x01, 0xa5, 0x49, 0xde, 0xa9, 0x95, 0x12, 0x4c, 0x10,
+	0x59, 0xb8, 0x80, 0x90, 0x10, 0x17, 0x4b, 0x70, 0x62, 0x4e, 0x89, 0x04, 0x33, 0x58, 0x02, 0xcc,
+	0x76, 0x32, 0x8d, 0x32, 0x4e, 0xcf, 0x2c, 0xc9, 0x49, 0x4c, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f,
+	0xcd, 0xc9, 0xac, 0xa8, 0xc8, 0x2c, 0xd2, 0x4f, 0xce, 0xc9, 0x4c, 0xcd, 0x2b, 0xd1, 0xc7, 0xe9,
+	0xab, 0x24, 0x36, 0xb0, 0x47, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x71, 0x89, 0x27, 0xcf,
+	0xf9, 0x00, 0x00, 0x00,
+}
diff --git a/connect/authenticated.proto b/connect/authenticated.proto
new file mode 100644
index 0000000000000000000000000000000000000000..926ca845e35c6a25e91ff4b1d4f477c2eaea5c2d
--- /dev/null
+++ b/connect/authenticated.proto
@@ -0,0 +1,22 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+syntax = "proto3";
+package authenticatedConnectionMessages;
+option go_package = "gitlab.com/elixxir/client/connect/authenticated";
+
+// Sent by the receiver of the authenticated connection request.
+message IdentityAuthentication {
+  bytes Signature      = 1;  // Signature of the connection fingerprint
+        // established between the two partners
+  bytes RsaPubKey = 2; // The RSA public key of the sender of this message,
+        // PEM-encoded
+  bytes Salt = 3; // Salt used to generate the network ID of the client
+}
+
+
+
diff --git a/connect/authenticated_test.go b/connect/authenticated_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3668a742229ed15a27af3697c8a1ae05ad7deca2
--- /dev/null
+++ b/connect/authenticated_test.go
@@ -0,0 +1,108 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"gitlab.com/elixxir/crypto/contact"
+	"gitlab.com/elixxir/crypto/diffieHellman"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/crypto/csprng"
+	"gitlab.com/xx_network/crypto/signature/rsa"
+	"gitlab.com/xx_network/crypto/xx"
+	"gitlab.com/xx_network/primitives/id"
+	"math/rand"
+	"testing"
+	"time"
+)
+
+// TestConnectWithAuthentication will test the client/server relationship for
+// an AuthenticatedConnection. This will construct a client which will send an
+// IdentityAuthentication message to the server, who will hear it and verify
+// the contents. This will use a mock connection interface and private
+// production code helper functions for easier testing.
+func TestConnectWithAuthentication(t *testing.T) {
+	grp := getGroup()
+	numPrimeByte := len(grp.GetPBytes())
+
+	// Set up cmix handler
+	mockNet := newMockCmix()
+
+	// Set up connect arguments
+	prng := rand.New(rand.NewSource(42))
+	dhPrivKey := diffieHellman.GeneratePrivateKey(
+		numPrimeByte, grp, prng)
+	dhPubKey := diffieHellman.GeneratePublicKey(dhPrivKey, grp)
+	salt := make([]byte, 32)
+	copy(salt, "salt")
+
+	myRsaPrivKey, err := rsa.LoadPrivateKeyFromPem(getPrivKey())
+	if err != nil {
+		t.Fatalf("Faled to load private key: %v", err)
+	}
+
+	// Construct client ID the proper way as server will need to verify it
+	// using the xx.NewID function call
+	myId, err := xx.NewID(myRsaPrivKey.GetPublic(), salt, id.User)
+	if err != nil {
+		t.Fatalf("Failed to generate client's id: %+v", err)
+	}
+
+	// Generate server ID using testing interface
+	serverID := id.NewIdFromString("server", id.User, t)
+
+	// Construct recipient
+	recipient := contact.Contact{
+		ID:       serverID,
+		DhPubKey: dhPubKey,
+	}
+
+	rng := fastRNG.NewStreamGenerator(1, 1,
+		csprng.NewSystemRNG)
+
+	// Create the mock connection, which will be shared by the client and
+	// server. This will send the client's request to the server internally
+	mockConn := newMockConnection(myId, serverID, dhPrivKey, dhPubKey)
+
+	// Set up the server's callback, which will pass the authenticated
+	// connection through via a channel
+	authConnChan := make(chan AuthenticatedConnection, 1)
+	serverCb := AuthenticatedCallback(
+		func(connection AuthenticatedConnection) {
+			authConnChan <- connection
+		})
+
+	// Initialize params with a shorter timeout to hasten test results
+	customParams := GetDefaultParams()
+	customParams.Timeout = 3 * time.Second
+
+	// Initialize the server
+	serverHandler := buildAuthConfirmationHandler(serverCb, mockConn)
+
+	// Pass the server's listener to the mock connection so the connection
+	// can pass the client's message directly to the server
+	mockConn.listener = serverHandler
+
+	// Initialize the client
+	_, err = connectWithAuthentication(mockConn, time.Now(), recipient,
+		salt, myRsaPrivKey, rng, mockNet,
+		customParams)
+	if err != nil {
+		t.Fatalf("ConnectWithAuthentication error: %+v", err)
+	}
+
+	// Wait for the server to establish it's connection via the callback
+	timeout := time.NewTimer(customParams.Timeout)
+	select {
+	case <-authConnChan:
+		return
+	case <-timeout.C:
+		t.Fatalf("Timed out waiting for server's authenticated connection " +
+			"to be established")
+	}
+
+}
diff --git a/connect/client.go b/connect/client.go
new file mode 100644
index 0000000000000000000000000000000000000000..a916bdca352da2e7aee21d0b2549702acfeebfdf
--- /dev/null
+++ b/connect/client.go
@@ -0,0 +1,54 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"github.com/golang/protobuf/proto"
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/crypto/signature/rsa"
+)
+
+// buildClientAuthRequest is a helper function which constructs a marshalled
+// IdentityAuthentication message.
+func buildClientAuthRequest(newPartner partner.Manager,
+	rng *fastRNG.StreamGenerator, rsaPrivKey *rsa.PrivateKey,
+	salt []byte) ([]byte, error) {
+
+	// The connection fingerprint (hashed) will be used as a nonce
+	connectionFp := newPartner.ConnectionFingerprint().Bytes()
+	opts := rsa.NewDefaultOptions()
+	h := opts.Hash.New()
+	h.Write(connectionFp)
+	nonce := h.Sum(nil)
+
+	// Sign the connection fingerprint
+	stream := rng.GetStream()
+	defer stream.Close()
+	signature, err := rsa.Sign(stream, rsaPrivKey,
+		opts.Hash, nonce, opts)
+	if err != nil {
+		return nil, errors.Errorf("failed to sign nonce: %+v", err)
+	}
+
+	// Construct message
+	pemEncodedRsaPubKey := rsa.CreatePublicKeyPem(rsaPrivKey.GetPublic())
+	iar := &IdentityAuthentication{
+		Signature: signature,
+		RsaPubKey: pemEncodedRsaPubKey,
+		Salt:      salt,
+	}
+	payload, err := proto.Marshal(iar)
+	if err != nil {
+		return nil, errors.Errorf("failed to marshal identity request "+
+			"message: %+v", err)
+	}
+
+	return payload, nil
+}
diff --git a/connect/connect.go b/connect/connect.go
index 6c9fb120e91d25695ad3f3f5ac0dd3578f07c9f7..1f0a6db7449f9c3fac9db297114997bce803fdd1 100644
--- a/connect/connect.go
+++ b/connect/connect.go
@@ -30,10 +30,17 @@ import (
 	"time"
 )
 
+const (
+	// connectionTimeout is the time.Duration for a connection
+	// to be established before the requester times out.
+	connectionTimeout = 15 * time.Second
+)
+
 // Connection is a wrapper for the E2E and auth packages.
 // It can be used to automatically establish an E2E partnership
 // with a partner.Manager, or be built from an existing E2E partnership.
-// You can then use this interface to send to and receive from the newly-established partner.Manager.
+// You can then use this interface to send to and receive from the
+// newly-established partner.Manager.
 type Connection interface {
 	// Closer deletes this Connection's partner.Manager and releases resources
 	io.Closer
@@ -41,7 +48,8 @@ type Connection interface {
 	// GetPartner returns the partner.Manager for this Connection
 	GetPartner() partner.Manager
 
-	// SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
+	// SendE2E is a wrapper for sending specifically to the Connection's
+	// partner.Manager
 	SendE2E(mt catalog.MessageType, payload []byte, params clientE2e.Params) (
 		[]id.Round, e2e.MessageID, time.Time, error)
 
@@ -53,37 +61,35 @@ type Connection interface {
 	Unregister(listenerID receive.ListenerID)
 }
 
-// Callback is the callback format required to retrieve new Connection objects as they are established
+// Callback is the callback format required to retrieve
+// new Connection objects as they are established.
 type Callback func(connection Connection)
 
-// handler provides an implementation for the Connection interface
-type handler struct {
-	partner partner.Manager
-	e2e     clientE2e.Handler
-	params  Params
-}
-
-// Params for managing Connection objects
+// Params for managing Connection objects.
 type Params struct {
-	Auth  auth.Param
-	Rekey rekey.Params
-	Event event.Reporter
+	Auth    auth.Param
+	Rekey   rekey.Params
+	Event   event.Reporter
+	Timeout time.Duration
 }
 
-// GetDefaultParams returns a usable set of default Connection parameters
+// GetDefaultParams returns a usable set of default Connection parameters.
 func GetDefaultParams() Params {
 	return Params{
-		Auth:  auth.GetDefaultParams(),
-		Rekey: rekey.GetDefaultParams(),
-		Event: event.NewEventManager(),
+		Auth:    auth.GetDefaultParams(),
+		Rekey:   rekey.GetDefaultParams(),
+		Event:   event.NewEventManager(),
+		Timeout: connectionTimeout,
 	}
 }
 
 // Connect performs auth key negotiation with the given recipient,
 // and returns a Connection object for the newly-created partner.Manager
-// This function is to be used sender-side and will block until the partner.Manager is confirmed
-func Connect(recipient contact.Contact, myId *id.ID, privKey *cyclic.Int, rng *fastRNG.StreamGenerator,
-	grp *cyclic.Group, net cmix.Client, p Params) (Connection, error) {
+// This function is to be used sender-side and will block until the
+// partner.Manager is confirmed.
+func Connect(recipient contact.Contact, myId *id.ID, privKey *cyclic.Int,
+	rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client,
+	p Params) (Connection, error) {
 
 	// Build an ephemeral KV
 	kv := versioned.NewKV(ekv.MakeMemstore())
@@ -119,23 +125,32 @@ func Connect(recipient contact.Contact, myId *id.ID, privKey *cyclic.Int, rng *f
 	}
 
 	// Block waiting for auth to confirm
-	jww.DEBUG.Printf("Connection waiting for auth request for %s to be confirmed...", recipient.ID.String())
-	newConnection := <-signalChannel
-
-	// Verify the Connection is complete
-	if newConnection == nil {
-		return nil, errors.Errorf("Unable to complete connection with partner %s", recipient.ID.String())
+	jww.DEBUG.Printf("Connection waiting for auth request "+
+		"for %s to be confirmed...", recipient.ID.String())
+	timeout := time.NewTimer(p.Timeout)
+	defer timeout.Stop()
+	select {
+	case newConnection := <-signalChannel:
+		// Verify the Connection is complete
+		if newConnection == nil {
+			return nil, errors.Errorf("Unable to complete connection "+
+				"with partner %s", recipient.ID.String())
+		}
+		jww.DEBUG.Printf("Connection auth request for %s confirmed",
+			recipient.ID.String())
+		return newConnection, nil
+	case <-timeout.C:
+		return nil, errors.Errorf("Connection request with "+
+			"partner %s timed out", recipient.ID.String())
 	}
-	jww.DEBUG.Printf("Connection auth request for %s confirmed", recipient.ID.String())
-
-	return newConnection, nil
 }
 
-// RegisterConnectionCallback assembles a Connection object on the reception-side
+// StartServer assembles a Connection object on the reception-side
 // and feeds it into the given Callback whenever an incoming request
 // for an E2E partnership with a partner.Manager is confirmed.
-func RegisterConnectionCallback(cb Callback, myId *id.ID, privKey *cyclic.Int, rng *fastRNG.StreamGenerator,
-	grp *cyclic.Group, net cmix.Client, p Params) error {
+func StartServer(cb Callback, myId *id.ID, privKey *cyclic.Int,
+	rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client,
+	p Params) error {
 
 	// Build an ephemeral KV
 	kv := versioned.NewKV(ekv.MakeMemstore())
@@ -154,14 +169,24 @@ func RegisterConnectionCallback(cb Callback, myId *id.ID, privKey *cyclic.Int, r
 	callback := getAuthCallback(cb, e2eHandler, p)
 
 	// Build auth object for E2E negotiation
-	_, err = auth.NewState(kv, net, e2eHandler,
+	authState, err := auth.NewState(kv, net, e2eHandler,
 		rng, p.Event, p.Auth, callback, nil)
+	callback.authState = authState
 	return err
 }
 
+// handler provides an implementation for the Connection interface.
+type handler struct {
+	partner partner.Manager
+	e2e     clientE2e.Handler
+	params  Params
+}
+
 // BuildConnection assembles a Connection object
-// after an E2E partnership has already been confirmed with the given partner.Manager
-func BuildConnection(partner partner.Manager, e2eHandler clientE2e.Handler, p Params) Connection {
+// after an E2E partnership has already been confirmed with the given
+// partner.Manager.
+func BuildConnection(partner partner.Manager, e2eHandler clientE2e.Handler,
+	p Params) Connection {
 	return &handler{
 		partner: partner,
 		params:  p,
@@ -169,36 +194,41 @@ func BuildConnection(partner partner.Manager, e2eHandler clientE2e.Handler, p Pa
 	}
 }
 
-// Close deletes this Connection's partner.Manager and releases resources
+// Close deletes this Connection's partner.Manager and releases resources.
 func (h *handler) Close() error {
 	return h.e2e.DeletePartner(h.partner.PartnerId())
 }
 
-// GetPartner returns the partner.Manager for this Connection
+// GetPartner returns the partner.Manager for this Connection.
 func (h *handler) GetPartner() partner.Manager {
 	return h.partner
 }
 
-// SendE2E is a wrapper for sending specifically to the Connection's partner.Manager
-func (h *handler) SendE2E(mt catalog.MessageType, payload []byte, params clientE2e.Params) (
+// SendE2E is a wrapper for sending specifically to the Connection's
+// partner.Manager.
+func (h *handler) SendE2E(mt catalog.MessageType, payload []byte,
+	params clientE2e.Params) (
 	[]id.Round, e2e.MessageID, time.Time, error) {
 	return h.e2e.SendE2E(mt, h.partner.PartnerId(), payload, params)
 }
 
 // RegisterListener is used for E2E reception
-// and allows for reading data sent from the partner.Manager
-func (h *handler) RegisterListener(messageType catalog.MessageType, newListener receive.Listener) receive.ListenerID {
-	return h.e2e.RegisterListener(h.partner.PartnerId(), messageType, newListener)
+// and allows for reading data sent from the partner.Manager.
+func (h *handler) RegisterListener(messageType catalog.MessageType,
+	newListener receive.Listener) receive.ListenerID {
+	return h.e2e.RegisterListener(h.partner.PartnerId(),
+		messageType, newListener)
 }
 
-// Unregister listener for E2E reception
+// Unregister listener for E2E reception.
 func (h *handler) Unregister(listenerID receive.ListenerID) {
 	h.e2e.Unregister(listenerID)
 }
 
-// authCallback provides callback functionality for interfacing between auth.State and Connection
-// This is used both for blocking creation of a Connection object until the auth Request is confirmed
-// and for dynamically building new Connection objects when an auth Request is received.
+// authCallback provides callback functionality for interfacing between
+// auth.State and Connection. This is used both for blocking creation of a
+// Connection object until the auth Request is confirmed and for dynamically
+// building new Connection objects when an auth Request is received.
 type authCallback struct {
 	// Used for signaling confirmation of E2E partnership
 	connectionCallback Callback
@@ -206,38 +236,54 @@ type authCallback struct {
 	// Used for building new Connection objects
 	connectionE2e    clientE2e.Handler
 	connectionParams Params
+	authState        auth.State
 }
 
-// getAuthCallback returns a callback interface to be passed into the creation of an auth.State object.
-func getAuthCallback(cb Callback, e2e clientE2e.Handler, params Params) authCallback {
-	return authCallback{
+// getAuthCallback returns a callback interface to be passed into the creation
+// of an auth.State object.
+func getAuthCallback(cb Callback, e2e clientE2e.Handler,
+	params Params) *authCallback {
+	return &authCallback{
 		connectionCallback: cb,
 		connectionE2e:      e2e,
 		connectionParams:   params,
 	}
 }
 
-// Confirm will be called when an auth Confirm message is processed
-func (a authCallback) Confirm(requestor contact.Contact, receptionID receptionID.EphemeralIdentity, round rounds.Round) {
-	jww.DEBUG.Printf("Connection auth request for %s confirmed", requestor.ID.String())
+// Confirm will be called when an auth Confirm message is processed.
+func (a authCallback) Confirm(requestor contact.Contact,
+	receptionID receptionID.EphemeralIdentity, round rounds.Round) {
+	jww.DEBUG.Printf("Connection auth request for %s confirmed",
+		requestor.ID.String())
 
 	// After confirmation, get the new partner
 	newPartner, err := a.connectionE2e.GetPartner(requestor.ID)
 	if err != nil {
-		jww.ERROR.Printf("Unable to build connection with partner %s: %+v", requestor.ID, err)
+		jww.ERROR.Printf("Unable to build connection with "+
+			"partner %s: %+v", requestor.ID, err)
 		// Send a nil connection to avoid hold-ups down the line
 		a.connectionCallback(nil)
 		return
 	}
 
 	// Return the new Connection object
-	a.connectionCallback(BuildConnection(newPartner, a.connectionE2e, a.connectionParams))
+	a.connectionCallback(BuildConnection(newPartner, a.connectionE2e,
+		a.connectionParams))
 }
 
-// Request will be called when an auth Request message is processed
-func (a authCallback) Request(requestor contact.Contact, receptionID receptionID.EphemeralIdentity, round rounds.Round) {
+// Request will be called when an auth Request message is processed.
+func (a authCallback) Request(requestor contact.Contact,
+	receptionID receptionID.EphemeralIdentity, round rounds.Round) {
+	_, err := a.authState.Confirm(requestor)
+	if err != nil {
+		jww.ERROR.Printf("Unable to build connection with "+
+			"partner %s: %+v", requestor.ID, err)
+		// Send a nil connection to avoid hold-ups down the line
+		a.connectionCallback(nil)
+	}
 }
 
-// Reset will be called when an auth Reset operation occurs
-func (a authCallback) Reset(requestor contact.Contact, receptionID receptionID.EphemeralIdentity, round rounds.Round) {
+// Reset will be called when an auth Reset operation occurs.
+func (a authCallback) Reset(requestor contact.Contact,
+	receptionID receptionID.EphemeralIdentity, round rounds.Round) {
 }
diff --git a/connect/generateProto.sh b/connect/generateProto.sh
new file mode 100755
index 0000000000000000000000000000000000000000..b27e351d7d0c5784e9564cfc2b1e6b2ba7889aa6
--- /dev/null
+++ b/connect/generateProto.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+# This script will generate the protobuf Golang file (pb.go) out of the protobuf file (.proto).
+# This is meant to be called from the top level of the repo.
+
+protoc --go_out=paths=source_relative:. connections/authenticated/authenticated.proto
diff --git a/connect/server.go b/connect/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..78e22eed6fedfbe965ac89dcd8cbdf15579d4a26
--- /dev/null
+++ b/connect/server.go
@@ -0,0 +1,132 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"github.com/golang/protobuf/proto"
+	"github.com/pkg/errors"
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/e2e/receive"
+	"gitlab.com/xx_network/crypto/signature/rsa"
+	"gitlab.com/xx_network/crypto/xx"
+	"gitlab.com/xx_network/primitives/id"
+)
+
+// authenticatedServerListenerName is the name of the client's
+//listener interface.
+const authenticatedServerListenerName = "AuthenticatedServerListener"
+
+// server is an interface that wraps receive.Listener. This handles
+// the server listening for the client's proof of identity message.
+type server interface {
+	receive.Listener
+}
+
+// serverListener provides an implementation of the server interface.
+// This will handle the identity message sent by the client.
+type serverListener struct {
+	// connectionCallback allows an AuthenticatedConnection
+	// to be passed back upon establishment.
+	connectionCallback AuthenticatedCallback
+
+	// conn used to retrieve the connection context with the partner.
+	conn Connection
+}
+
+// buildAuthConfirmationHandler returns a serverListener object.
+// This will handle incoming identity authentication confirmations
+// via the serverListener.Hear method. A successful AuthenticatedConnection
+// will be passed along via the serverListener.connectionCallback
+func buildAuthConfirmationHandler(cb AuthenticatedCallback,
+	connection Connection) server {
+	return &serverListener{
+		connectionCallback: cb,
+		conn:               connection,
+	}
+}
+
+// Hear handles the reception of an IdentityAuthentication by the
+// server. It will attempt to verify the identity confirmation of
+// the given client.
+func (a serverListener) Hear(item receive.Message) {
+	// Process the message data into a protobuf
+	iar := &IdentityAuthentication{}
+	err := proto.Unmarshal(item.Payload, iar)
+	if err != nil {
+		a.handleAuthConfirmationErr(err, item.Sender)
+		return
+	}
+
+	// Process the PEM encoded public key to an rsa.PublicKey object
+	partnerPubKey, err := rsa.LoadPublicKeyFromPem(iar.RsaPubKey)
+	if err != nil {
+		a.handleAuthConfirmationErr(err, item.Sender)
+		return
+	}
+
+	// Get the new partner
+	newPartner := a.conn.GetPartner()
+
+	// Verify the partner's known ID against the information passed
+	// along the wire
+	partnerWireId, err := xx.NewID(partnerPubKey, iar.Salt, id.User)
+	if err != nil {
+		a.handleAuthConfirmationErr(err, item.Sender)
+		return
+	}
+
+	if !newPartner.PartnerId().Cmp(partnerWireId) {
+		err = errors.New("Failed confirm partner's ID over the wire")
+		a.handleAuthConfirmationErr(err, item.Sender)
+		return
+	}
+
+	// The connection fingerprint (hashed) will be used as a nonce
+	connectionFp := newPartner.ConnectionFingerprint().Bytes()
+
+	// Hash the connection fingerprint
+	opts := rsa.NewDefaultOptions()
+	h := opts.Hash.New()
+	h.Write(connectionFp)
+	nonce := h.Sum(nil)
+
+	// Verify the signature
+	err = rsa.Verify(partnerPubKey, opts.Hash, nonce, iar.Signature, opts)
+	if err != nil {
+		a.handleAuthConfirmationErr(err, item.Sender)
+		return
+	}
+
+	// If successful, pass along the established authenticated connection
+	// via the callback
+	jww.DEBUG.Printf("AuthenticatedConnection auth request for %s confirmed",
+		item.Sender.String())
+	authConn := buildAuthenticatedConnection(a.conn)
+	authConn.setAuthenticated()
+	go a.connectionCallback(authConn)
+}
+
+// handleAuthConfirmationErr is a helper function which will close the connection
+// between the server and the client. It will also print out the passed in error.
+func (a serverListener) handleAuthConfirmationErr(err error, sender *id.ID) {
+	jww.ERROR.Printf("Unable to build connection with "+
+		"partner %s: %+v", sender, err)
+	// Send a nil connection to avoid hold-ups down the line
+	a.connectionCallback(nil)
+	err = a.conn.Close()
+	if err != nil {
+		jww.ERROR.Printf("Failed to close connection with partner %s: %v",
+			sender, err)
+	}
+}
+
+// Name returns the name of this listener. This is typically for
+// printing/debugging purposes.
+func (a serverListener) Name() string {
+	return authenticatedServerListenerName
+}
diff --git a/connect/utils_test.go b/connect/utils_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..39f518b15a92bc9c588558eb4ee3fb4f52997f3f
--- /dev/null
+++ b/connect/utils_test.go
@@ -0,0 +1,484 @@
+package connect
+
+import (
+	"github.com/cloudflare/circl/dh/sidh"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/cmix"
+	"gitlab.com/elixxir/client/cmix/gateway"
+	"gitlab.com/elixxir/client/cmix/identity"
+	"gitlab.com/elixxir/client/cmix/message"
+	"gitlab.com/elixxir/client/cmix/rounds"
+	"gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner"
+	"gitlab.com/elixxir/client/e2e/ratchet/partner/session"
+	"gitlab.com/elixxir/client/e2e/receive"
+	"gitlab.com/elixxir/client/stoppable"
+	"gitlab.com/elixxir/comms/network"
+	"gitlab.com/elixxir/crypto/contact"
+	"gitlab.com/elixxir/crypto/cyclic"
+	cryptoE2e "gitlab.com/elixxir/crypto/e2e"
+	"gitlab.com/elixxir/primitives/format"
+	"gitlab.com/xx_network/comms/connect"
+	"gitlab.com/xx_network/crypto/large"
+	"gitlab.com/xx_network/primitives/id"
+	"gitlab.com/xx_network/primitives/id/ephemeral"
+	"gitlab.com/xx_network/primitives/ndf"
+	"gitlab.com/xx_network/primitives/netTime"
+	"time"
+)
+
+////////////////////////////////////////////////////////////////////////////////
+// Mock Partner Interface                                                           //
+////////////////////////////////////////////////////////////////////////////////
+
+type mockPartner struct {
+	partnerId       *id.ID
+	myID            *id.ID
+	myDhPrivKey     *cyclic.Int
+	partnerDhPubKey *cyclic.Int
+}
+
+func newMockPartner(partnerId, myId *id.ID,
+	myDhPrivKey, partnerDhPubKey *cyclic.Int) *mockPartner {
+	return &mockPartner{
+		partnerId:       partnerId,
+		myID:            myId,
+		myDhPrivKey:     myDhPrivKey,
+		partnerDhPubKey: partnerDhPubKey,
+	}
+}
+
+func (m mockPartner) PartnerId() *id.ID {
+	return m.partnerId
+}
+
+func (m mockPartner) MyId() *id.ID {
+	return m.myID
+}
+
+func (m mockPartner) MyRootPrivateKey() *cyclic.Int {
+	return m.myDhPrivKey
+}
+
+func (m mockPartner) PartnerRootPublicKey() *cyclic.Int {
+	return m.partnerDhPubKey
+}
+
+func (m mockPartner) SendRelationshipFingerprint() []byte {
+	return nil
+}
+
+func (m mockPartner) ReceiveRelationshipFingerprint() []byte {
+	return nil
+}
+
+func (m mockPartner) ConnectionFingerprint() partner.ConnectionFp {
+	return partner.ConnectionFp{}
+}
+
+func (m mockPartner) Contact() contact.Contact {
+	return contact.Contact{
+		ID:       m.partnerId,
+		DhPubKey: m.partnerDhPubKey,
+	}
+}
+
+func (m mockPartner) PopSendCypher() (*session.Cypher, error) {
+	return nil, nil
+}
+
+func (m mockPartner) PopRekeyCypher() (*session.Cypher, error) {
+	return nil, nil
+}
+
+func (m mockPartner) NewReceiveSession(partnerPubKey *cyclic.Int, partnerSIDHPubKey *sidh.PublicKey, e2eParams session.Params, source *session.Session) (*session.Session, bool) {
+	return nil, false
+}
+
+func (m mockPartner) NewSendSession(myDHPrivKey *cyclic.Int, mySIDHPrivateKey *sidh.PrivateKey, e2eParams session.Params, source *session.Session) *session.Session {
+	return nil
+}
+
+func (m mockPartner) GetSendSession(sid session.SessionID) *session.Session {
+	return nil
+}
+
+func (m mockPartner) GetReceiveSession(sid session.SessionID) *session.Session {
+	return nil
+}
+
+func (m mockPartner) Confirm(sid session.SessionID) error {
+	return nil
+}
+
+func (m mockPartner) TriggerNegotiations() []*session.Session {
+	return nil
+}
+
+func (m mockPartner) MakeService(tag string) message.Service {
+	return message.Service{}
+}
+
+func (m mockPartner) Delete() error {
+	return nil
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Mock Connection Interface                                                           //
+////////////////////////////////////////////////////////////////////////////////
+
+type mockConnection struct {
+	partner     *mockPartner
+	payloadChan chan []byte
+	listener    server
+}
+
+func newMockConnection(partnerId, myId *id.ID,
+	myDhPrivKey, partnerDhPubKey *cyclic.Int) *mockConnection {
+
+	return &mockConnection{
+		partner: newMockPartner(partnerId, myId,
+			myDhPrivKey, partnerDhPubKey),
+		payloadChan: make(chan []byte, 1),
+	}
+}
+
+func (m mockConnection) Close() error {
+	return nil
+}
+
+func (m mockConnection) GetPartner() partner.Manager {
+	return m.partner
+}
+
+func (m mockConnection) SendE2E(mt catalog.MessageType, payload []byte, params e2e.Params) ([]id.Round, cryptoE2e.MessageID, time.Time, error) {
+	m.payloadChan <- payload
+	m.listener.Hear(receive.Message{
+		MessageType: mt,
+		Payload:     payload,
+		Sender:      m.partner.myID,
+		RecipientID: m.partner.partnerId,
+	})
+	return nil, cryptoE2e.MessageID{}, time.Time{}, nil
+}
+
+func (m mockConnection) RegisterListener(messageType catalog.MessageType, newListener receive.Listener) receive.ListenerID {
+	return receive.ListenerID{}
+}
+
+func (m mockConnection) Unregister(listenerID receive.ListenerID) {
+
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Mock cMix Client                                                           //
+////////////////////////////////////////////////////////////////////////////////
+
+type mockCmix struct {
+	instance *network.Instance
+}
+
+func newMockCmix() *mockCmix {
+
+	return &mockCmix{}
+}
+
+func (m mockCmix) Connect(ndf *ndf.NetworkDefinition) error {
+	return nil
+}
+
+func (m *mockCmix) Follow(report cmix.ClientErrorReport) (stoppable.Stoppable, error) {
+	return nil, nil
+}
+
+func (m *mockCmix) GetMaxMessageLength() int {
+	return 4096
+}
+
+func (m *mockCmix) Send(recipient *id.ID, fingerprint format.Fingerprint,
+	service message.Service, payload, mac []byte,
+	cmixParams cmix.CMIXParams) (id.Round, ephemeral.Id, error) {
+
+	return 0, ephemeral.Id{}, nil
+}
+
+func (m *mockCmix) SendMany(messages []cmix.TargetedCmixMessage, p cmix.CMIXParams) (id.Round, []ephemeral.Id, error) {
+	return 0, []ephemeral.Id{}, nil
+}
+
+func (m *mockCmix) AddIdentity(id *id.ID, validUntil time.Time, persistent bool) {
+}
+
+func (m *mockCmix) RemoveIdentity(id *id.ID) {
+}
+
+func (m *mockCmix) GetIdentity(get *id.ID) (identity.TrackedID, error) {
+	return identity.TrackedID{
+		Creation: netTime.Now().Add(-time.Minute),
+	}, nil
+}
+
+func (m *mockCmix) AddFingerprint(identity *id.ID, fp format.Fingerprint, mp message.Processor) error {
+	return nil
+}
+
+func (m *mockCmix) DeleteFingerprint(identity *id.ID, fingerprint format.Fingerprint) {
+	return
+}
+
+func (m *mockCmix) DeleteClientFingerprints(identity *id.ID) {
+	return
+}
+
+func (m *mockCmix) AddService(clientID *id.ID, newService message.Service, response message.Processor) {
+	return
+}
+
+func (m *mockCmix) DeleteService(clientID *id.ID, toDelete message.Service, processor message.Processor) {
+	return
+}
+
+func (m *mockCmix) DeleteClientService(clientID *id.ID) {
+}
+
+func (m *mockCmix) TrackServices(tracker message.ServicesTracker) {
+	return
+}
+
+func (m *mockCmix) CheckInProgressMessages() {
+	return
+}
+
+func (m *mockCmix) IsHealthy() bool {
+	return true
+}
+
+func (m *mockCmix) WasHealthy() bool {
+	return true
+}
+
+func (m *mockCmix) AddHealthCallback(f func(bool)) uint64 {
+	return 0
+}
+
+func (m *mockCmix) RemoveHealthCallback(u uint64) {
+	return
+}
+
+func (m *mockCmix) HasNode(nid *id.ID) bool {
+	return true
+}
+
+func (m *mockCmix) NumRegisteredNodes() int {
+	return 24
+}
+
+func (m *mockCmix) TriggerNodeRegistration(nid *id.ID) {
+	return
+}
+
+func (m *mockCmix) GetRoundResults(timeout time.Duration, roundCallback cmix.RoundEventCallback, roundList ...id.Round) error {
+	roundCallback(true, false, nil)
+	return nil
+}
+
+func (m *mockCmix) LookupHistoricalRound(rid id.Round, callback rounds.RoundResultCallback) error {
+	return nil
+}
+
+func (m *mockCmix) SendToAny(sendFunc func(host *connect.Host) (interface{}, error), stop *stoppable.Single) (interface{}, error) {
+	return nil, nil
+}
+
+func (m *mockCmix) SendToPreferred(targets []*id.ID, sendFunc gateway.SendToPreferredFunc, stop *stoppable.Single, timeout time.Duration) (interface{}, error) {
+	return nil, nil
+}
+
+func (m *mockCmix) SetGatewayFilter(f gateway.Filter) {
+	return
+}
+
+func (m *mockCmix) GetHostParams() connect.HostParams {
+	return connect.GetDefaultHostParams()
+}
+
+func (m *mockCmix) GetAddressSpace() uint8 {
+	return 32
+}
+
+func (m *mockCmix) RegisterAddressSpaceNotification(tag string) (chan uint8, error) {
+	return nil, nil
+}
+
+func (m *mockCmix) UnregisterAddressSpaceNotification(tag string) {
+	return
+}
+
+func (m *mockCmix) GetInstance() *network.Instance {
+	return m.instance
+}
+
+func (m *mockCmix) GetVerboseRounds() string {
+	return ""
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Misc set-up utils                                                          //
+////////////////////////////////////////////////////////////////////////////////
+
+var testCert = `-----BEGIN CERTIFICATE-----
+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
+EnretBzQkeKeBwoB2u6NTiOmUjk=
+-----END CERTIFICATE-----
+`
+
+func getNDF() *ndf.NetworkDefinition {
+	return &ndf.NetworkDefinition{
+		UDB: ndf.UDB{
+			ID:       id.DummyUser.Bytes(),
+			Cert:     testCert,
+			Address:  "address",
+			DhPubKey: []byte{123, 34, 86, 97, 108, 117, 101, 34, 58, 53, 48, 49, 53, 53, 53, 52, 54, 53, 49, 48, 54, 49, 56, 57, 53, 54, 51, 48, 54, 52, 49, 51, 53, 49, 57, 56, 55, 57, 52, 57, 50, 48, 56, 49, 52, 57, 52, 50, 57, 51, 57, 53, 49, 50, 51, 54, 52, 56, 49, 57, 55, 48, 50, 50, 49, 48, 55, 55, 50, 52, 52, 48, 49, 54, 57, 52, 55, 52, 57, 53, 53, 56, 55, 54, 50, 57, 53, 57, 53, 48, 54, 55, 57, 55, 48, 53, 48, 48, 54, 54, 56, 49, 57, 50, 56, 48, 52, 48, 53, 51, 50, 48, 57, 55, 54, 56, 56, 53, 57, 54, 57, 56, 57, 49, 48, 54, 56, 54, 50, 52, 50, 52, 50, 56, 49, 48, 51, 51, 51, 54, 55, 53, 55, 54, 52, 51, 54, 55, 54, 56, 53, 56, 48, 55, 56, 49, 52, 55, 49, 52, 53, 49, 52, 52, 52, 52, 53, 51, 57, 57, 51, 57, 57, 53, 50, 52, 52, 53, 51, 56, 48, 49, 48, 54, 54, 55, 48, 52, 50, 49, 55, 54, 57, 53, 57, 57, 57, 51, 52, 48, 54, 54, 54, 49, 50, 48, 54, 56, 57, 51, 54, 57, 48, 52, 55, 55, 54, 50, 49, 49, 56, 56, 53, 51, 50, 57, 57, 50, 54, 53, 48, 52, 57, 51, 54, 55, 54, 48, 57, 56, 56, 49, 55, 52, 52, 57, 53, 57, 54, 53, 50, 55, 53, 52, 52, 52, 49, 57, 55, 49, 54, 50, 52, 52, 56, 50, 55, 55, 50, 49, 48, 53, 56, 56, 57, 54, 51, 53, 54, 54, 53, 53, 53, 53, 49, 56, 50, 53, 49, 49, 50, 57, 50, 48, 49, 56, 48, 48, 54, 49, 56, 57, 48, 55, 48, 51, 53, 51, 51, 56, 57, 52, 49, 50, 57, 49, 55, 50, 56, 55, 57, 57, 52, 55, 53, 51, 49, 55, 55, 48, 53, 55, 55, 49, 50, 51, 57, 49, 51, 55, 54, 48, 50, 49, 55, 50, 54, 54, 52, 56, 52, 48, 48, 54, 48, 52, 48, 53, 56, 56, 53, 54, 52, 56, 56, 49, 52, 52, 51, 57, 56, 51, 51, 57, 54, 55, 48, 49, 53, 55, 52, 53, 50, 56, 51, 49, 51, 48, 53, 52, 49, 49, 49, 49, 49, 56, 51, 53, 52, 52, 52, 52, 48, 53, 54, 57, 48, 54, 52, 56, 57, 52, 54, 53, 50, 56, 51, 53, 50, 48, 48, 50, 48, 48, 49, 50, 51, 51, 48, 48, 53, 48, 49, 50, 52, 56, 57, 48, 49, 51, 54, 55, 52, 57, 55, 50, 49, 48, 55, 53, 54, 49, 50, 52, 52, 57, 55, 48, 50, 56, 55, 55, 51, 51, 50, 53, 50, 48, 57, 52, 56, 57, 49, 49, 56, 49, 54, 57, 50, 55, 50, 51, 57, 51, 57, 54, 50, 56, 48, 54, 54, 49, 57, 55, 48, 50, 48, 57, 49, 51, 54, 50, 49, 50, 53, 50, 54, 50, 53, 53, 55, 57, 54, 51, 56, 49, 57, 48, 51, 49, 54, 54, 53, 51, 56, 56, 49, 48, 56, 48, 51, 57, 53, 49, 53, 53, 55, 49, 53, 57, 48, 57, 57, 55, 49, 56, 53, 55, 54, 48, 50, 54, 48, 49, 55, 57, 52, 55, 53, 51, 57, 49, 51, 53, 52, 49, 48, 50, 49, 55, 52, 51, 57, 48, 50, 56, 48, 50, 51, 53, 51, 54, 56, 49, 56, 50, 49, 55, 50, 57, 52, 51, 49, 56, 48, 56, 56, 50, 51, 53, 52, 56, 55, 49, 52, 55, 53, 50, 56, 48, 57, 55, 49, 53, 48, 48, 51, 50, 48, 57, 50, 50, 53, 50, 56, 51, 57, 55, 57, 49, 57, 50, 53, 56, 51, 55, 48, 51, 57, 54, 48, 50, 55, 54, 48, 54, 57, 55, 52, 53, 54, 52, 51, 56, 52, 53, 54, 48, 51, 57, 55, 55, 55, 49, 53, 57, 57, 49, 57, 52, 57, 56, 56, 54, 56, 50, 49, 49, 54, 56, 55, 56, 55, 51, 51, 57, 52, 53, 49, 52, 52, 55, 57, 53, 57, 49, 57, 52, 48, 51, 53, 49, 49, 49, 51, 48, 53, 54, 54, 50, 49, 56, 57, 52, 55, 50, 49, 54, 53, 57, 53, 50, 57, 50, 48, 51, 51, 52, 48, 56, 55, 54, 50, 49, 49, 49, 56, 53, 54, 57, 51, 57, 50, 53, 48, 53, 56, 56, 55, 56, 53, 54, 55, 51, 56, 55, 50, 53, 57, 56, 52, 54, 53, 49, 51, 50, 54, 51, 50, 48, 56, 56, 57, 52, 53, 57, 53, 56, 57, 57, 54, 52, 55, 55, 50, 57, 51, 51, 52, 55, 51, 48, 52, 56, 56, 50, 51, 50, 52, 53, 48, 51, 50, 56, 56, 50, 49, 55, 51, 51, 53, 54, 55, 51, 50, 51, 52, 56, 53, 52, 55, 48, 51, 56, 50, 51, 49, 53, 55, 52, 53, 53, 48, 55, 55, 56, 55, 48, 50, 51, 52, 50, 53, 52, 51, 48, 57, 56, 56, 54, 56, 54, 49, 57, 54, 48, 55, 55, 52, 57, 55, 56, 51, 48, 51, 57, 49, 55, 52, 49, 51, 49, 54, 57, 54, 50, 49, 52, 50, 55, 57, 55, 56, 56, 51, 49, 55, 51, 50, 54, 56, 49, 56, 53, 57, 48, 49, 49, 53, 48, 52, 53, 51, 51, 56, 52, 57, 57, 55, 54, 51, 55, 55, 48, 55, 49, 52, 50, 49, 54, 48, 49, 54, 52, 49, 57, 53, 56, 49, 54, 50, 55, 49, 52, 49, 52, 56, 49, 51, 52, 50, 53, 56, 55, 53, 57, 55, 52, 49, 57, 49, 55, 51, 55, 49, 51, 57, 54, 51, 49, 51, 49, 56, 53, 50, 49, 53, 52, 49, 51, 44, 34, 70, 105, 110, 103, 101, 114, 112, 114, 105, 110, 116, 34, 58, 49, 54, 56, 48, 49, 53, 52, 49, 53, 49, 49, 50, 51, 51, 48, 57, 56, 51, 54, 51, 125},
+		},
+		E2E: ndf.Group{
+			Prime: "E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D49413394C049B7A" +
+				"8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688B55B3D" +
+				"D2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E78615" +
+				"75E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC" +
+				"6ADC718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C" +
+				"4A530E8FFB1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F2" +
+				"6E5785302BEDBCA23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE" +
+				"448EEF78E184C7242DD161C7738F32BF29A841698978825B4111B4BC3E1E" +
+				"198455095958333D776D8B2BEEED3A1A1A221A6E37E664A64B83981C46FF" +
+				"DDC1A45E3D5211AAF8BFBC072768C4F50D7D7803D2D4F278DE8014A47323" +
+				"631D7E064DE81C0C6BFA43EF0E6998860F1390B5D3FEACAF1696015CB79C" +
+				"3F9C2D93D961120CD0E5F12CBB687EAB045241F96789C38E89D796138E63" +
+				"19BE62E35D87B1048CA28BE389B575E994DCA755471584A09EC723742DC3" +
+				"5873847AEF49F66E43873",
+			Generator: "2",
+		},
+		CMIX: ndf.Group{
+			Prime: "9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642" +
+				"F0B5C48C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757" +
+				"264E5A1A44FFE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F" +
+				"9716BFE6117C6B5B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091E" +
+				"B51743BF33050C38DE235567E1B34C3D6A5C0CEAA1A0F368213C3D19843D" +
+				"0B4B09DCB9FC72D39C8DE41F1BF14D4BB4563CA28371621CAD3324B6A2D3" +
+				"92145BEBFAC748805236F5CA2FE92B871CD8F9C36D3292B5509CA8CAA77A" +
+				"2ADFC7BFD77DDA6F71125A7456FEA153E433256A2261C6A06ED3693797E7" +
+				"995FAD5AABBCFBE3EDA2741E375404AE25B",
+			Generator: "5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E2480" +
+				"9670716C613D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D" +
+				"1AA58C4328A06C46A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A33" +
+				"8661D10461C0D135472085057F3494309FFA73C611F78B32ADBB5740C361" +
+				"C9F35BE90997DB2014E2EF5AA61782F52ABEB8BD6432C4DD097BC5423B28" +
+				"5DAFB60DC364E8161F4A2A35ACA3A10B1C4D203CC76A470A33AFDCBDD929" +
+				"59859ABD8B56E1725252D78EAC66E71BA9AE3F1DD2487199874393CD4D83" +
+				"2186800654760E1E34C09E4D155179F9EC0DC4473F996BDCE6EED1CABED8" +
+				"B6F116F7AD9CF505DF0F998E34AB27514B0FFE7",
+		},
+	}
+}
+
+func getGroup() *cyclic.Group {
+	return cyclic.NewGroup(
+		large.NewIntFromString("E2EE983D031DC1DB6F1A7A67DF0E9A8E5561DB8E8D4941"+
+			"3394C049B7A8ACCEDC298708F121951D9CF920EC5D146727AA4AE535B0922C688"+
+			"B55B3DD2AEDF6C01C94764DAB937935AA83BE36E67760713AB44A6337C20E7861"+
+			"575E745D31F8B9E9AD8412118C62A3E2E29DF46B0864D0C951C394A5CBBDC6ADC"+
+			"718DD2A3E041023DBB5AB23EBB4742DE9C1687B5B34FA48C3521632C4A530E8FF"+
+			"B1BC51DADDF453B0B2717C2BC6669ED76B4BDD5C9FF558E88F26E5785302BEDBC"+
+			"A23EAC5ACE92096EE8A60642FB61E8F3D24990B8CB12EE448EEF78E184C7242DD"+
+			"161C7738F32BF29A841698978825B4111B4BC3E1E198455095958333D776D8B2B"+
+			"EEED3A1A1A221A6E37E664A64B83981C46FFDDC1A45E3D5211AAF8BFBC072768C"+
+			"4F50D7D7803D2D4F278DE8014A47323631D7E064DE81C0C6BFA43EF0E6998860F"+
+			"1390B5D3FEACAF1696015CB79C3F9C2D93D961120CD0E5F12CBB687EAB045241F"+
+			"96789C38E89D796138E6319BE62E35D87B1048CA28BE389B575E994DCA7554715"+
+			"84A09EC723742DC35873847AEF49F66E43873", 16),
+		large.NewIntFromString("2", 16))
+}
+
+func getPrivKey() []byte {
+	return []byte(`-----BEGIN PRIVATE KEY-----
+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
+OaRA5ZbdE7g7vxKRV36jT3wvD7W+
+-----END PRIVATE KEY-----`)
+}
diff --git a/restlike/connect/receiver.go b/restlike/connect/receiver.go
new file mode 100644
index 0000000000000000000000000000000000000000..d6e87c57489a4235cd0e225fb38c4c87dad4afc3
--- /dev/null
+++ b/restlike/connect/receiver.go
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 Privategrity Corporation                                   /
+//                                                                             /
+// All rights reserved.                                                        /
+////////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"github.com/pkg/errors"
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/connect"
+	"gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/e2e/receive"
+	"gitlab.com/elixxir/client/restlike"
+	"google.golang.org/protobuf/proto"
+)
+
+// receiver is the reception handler for a RestServer
+type receiver struct {
+	conn      connect.Connection
+	endpoints *restlike.Endpoints
+}
+
+// Hear handles connect.Connection message reception for a RestServer
+// Automatically responds to invalid endpoint requests
+func (c receiver) Hear(item receive.Message) {
+	// Unmarshal the request payload
+	newMessage := &restlike.Message{}
+	err := proto.Unmarshal(item.Payload, newMessage)
+	if err != nil {
+		jww.ERROR.Printf("Unable to unmarshal restlike message: %+v", err)
+		return
+	}
+
+	var respondErr error
+	if cb, err := c.endpoints.Get(restlike.URI(newMessage.GetUri()), restlike.Method(newMessage.GetMethod())); err == nil {
+		// Send the payload to the proper Callback if it exists and singleRespond with the result
+		respondErr = respond(cb(newMessage), c.conn)
+	} else {
+		// If no callback, automatically send an error response
+		respondErr = respond(&restlike.Message{Error: err.Error()}, c.conn)
+	}
+	if respondErr != nil {
+		jww.ERROR.Printf("Unable to singleRespond to request: %+v", err)
+	}
+}
+
+// respond to connect.Connection with the given Message
+func respond(response *restlike.Message, conn connect.Connection) error {
+	payload, err := proto.Marshal(response)
+	if err != nil {
+		return errors.Errorf("unable to marshal restlike response message: %+v", err)
+	}
+
+	// TODO: Parameterize params
+	_, _, _, err = conn.SendE2E(catalog.XxMessage, payload, e2e.GetDefaultParams())
+	if err != nil {
+		return errors.Errorf("unable to send restlike response message: %+v", err)
+	}
+	return nil
+}
+
+// Name is used for debugging
+func (c receiver) Name() string {
+	return "Restlike"
+}
diff --git a/restlike/connect/receiver_test.go b/restlike/connect/receiver_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..723ec019fbedf4532b4f2a3d2bf3f66be51d36b1
--- /dev/null
+++ b/restlike/connect/receiver_test.go
@@ -0,0 +1,21 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 Privategrity Corporation                                   /
+//                                                                             /
+// All rights reserved.                                                        /
+////////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"gitlab.com/elixxir/client/e2e/receive"
+	"gitlab.com/elixxir/client/restlike"
+	"testing"
+)
+
+// Test failure of proto unmarshal
+func TestSingleReceiver_Callback_FailUnmarshal(t *testing.T) {
+	ep := restlike.NewEndpoints()
+	r := receiver{endpoints: ep}
+
+	r.Hear(receive.Message{Payload: []byte("test")})
+}
diff --git a/restlike/connect/request.go b/restlike/connect/request.go
new file mode 100644
index 0000000000000000000000000000000000000000..3d836f2ad7377365bd83b4fc6abb214b7bb88b37
--- /dev/null
+++ b/restlike/connect/request.go
@@ -0,0 +1,89 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 Privategrity Corporation                                   /
+//                                                                             /
+// All rights reserved.                                                        /
+////////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/connect"
+	"gitlab.com/elixxir/client/e2e"
+	"gitlab.com/elixxir/client/restlike"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/xx_network/crypto/csprng"
+	"google.golang.org/protobuf/proto"
+)
+
+// Request allows for making REST-like requests to a RestServer using connect.Connection
+// Can be used as stateful or declared inline without state
+type Request struct {
+	Net    connect.Connection
+	Rng    csprng.Source
+	E2eGrp *cyclic.Group
+}
+
+// Request provides several Method of sending Data to the given URI
+// and blocks until the Message is returned
+func (s *Request) Request(method restlike.Method, path restlike.URI,
+	content restlike.Data, headers *restlike.Headers, e2eParams e2e.Params) (*restlike.Message, error) {
+	// Build the Message
+	newMessage := &restlike.Message{
+		Content: content,
+		Headers: headers,
+		Method:  uint32(method),
+		Uri:     string(path),
+	}
+	msg, err := proto.Marshal(newMessage)
+	if err != nil {
+		return nil, err
+	}
+
+	// Build callback for the response
+	signalChannel := make(chan *restlike.Message, 1)
+	cb := func(msg *restlike.Message) {
+		signalChannel <- msg
+	}
+	s.Net.RegisterListener(catalog.XxMessage, response{responseCallback: cb})
+
+	// Transmit the Message
+	_, _, _, err = s.Net.SendE2E(catalog.XxMessage, msg, e2eParams)
+	if err != nil {
+		return nil, err
+	}
+
+	// Block waiting for single-use response
+	jww.DEBUG.Printf("Restlike waiting for connect response from %s...",
+		s.Net.GetPartner().PartnerId().String())
+	newResponse := <-signalChannel
+	jww.DEBUG.Printf("Restlike connect response received from %s",
+		s.Net.GetPartner().PartnerId().String())
+
+	return newResponse, nil
+}
+
+// AsyncRequest provides several Method of sending Data to the given URI
+// and will return the Message to the given Callback when received
+func (s *Request) AsyncRequest(method restlike.Method, path restlike.URI,
+	content restlike.Data, headers *restlike.Headers, cb restlike.RequestCallback, e2eParams e2e.Params) error {
+	// Build the Message
+	newMessage := &restlike.Message{
+		Content: content,
+		Headers: headers,
+		Method:  uint32(method),
+		Uri:     string(path),
+	}
+	msg, err := proto.Marshal(newMessage)
+	if err != nil {
+		return err
+	}
+
+	// Build callback for the response
+	s.Net.RegisterListener(catalog.XxMessage, response{responseCallback: cb})
+
+	// Transmit the Message
+	_, _, _, err = s.Net.SendE2E(catalog.XxMessage, msg, e2eParams)
+	return err
+}
diff --git a/restlike/connect/response.go b/restlike/connect/response.go
new file mode 100644
index 0000000000000000000000000000000000000000..99042d7c4bd4947a2f2eed560f4fef8114998d9d
--- /dev/null
+++ b/restlike/connect/response.go
@@ -0,0 +1,37 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 Privategrity Corporation                                   /
+//                                                                             /
+// All rights reserved.                                                        /
+////////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"gitlab.com/elixxir/client/e2e/receive"
+	"gitlab.com/elixxir/client/restlike"
+	"google.golang.org/protobuf/proto"
+)
+
+// response is the response handler for a Request
+type response struct {
+	responseCallback restlike.RequestCallback
+}
+
+// Hear handles for connect.Connection message responses for a Request
+func (r response) Hear(item receive.Message) {
+	newMessage := &restlike.Message{}
+
+	// Unmarshal the payload
+	err := proto.Unmarshal(item.Payload, newMessage)
+	if err != nil {
+		newMessage.Error = err.Error()
+	}
+
+	// Send the response payload to the responseCallback
+	r.responseCallback(newMessage)
+}
+
+// Name is used for debugging
+func (r response) Name() string {
+	return "Restlike"
+}
diff --git a/restlike/connect/response_test.go b/restlike/connect/response_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f10ea9d8292d7905105edb94b6533347715a4211
--- /dev/null
+++ b/restlike/connect/response_test.go
@@ -0,0 +1,76 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 Privategrity Corporation                                   /
+//                                                                             /
+// All rights reserved.                                                        /
+////////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"bytes"
+	"gitlab.com/elixxir/client/e2e/receive"
+	"gitlab.com/elixxir/client/restlike"
+	"google.golang.org/protobuf/proto"
+	"testing"
+	"time"
+)
+
+// Test happy path
+func TestSingleResponse_Callback(t *testing.T) {
+	resultChan := make(chan *restlike.Message, 1)
+	cb := func(input *restlike.Message) {
+		resultChan <- input
+	}
+	testPath := "test/path"
+	testMethod := restlike.Get
+	testMessage := &restlike.Message{
+		Content: []byte("test"),
+		Headers: nil,
+		Method:  uint32(testMethod),
+		Uri:     testPath,
+		Error:   "",
+	}
+
+	r := response{cb}
+
+	testPayload, err := proto.Marshal(testMessage)
+	if err != nil {
+		t.Errorf(err.Error())
+	}
+	r.Hear(receive.Message{Payload: testPayload})
+
+	select {
+	case result := <-resultChan:
+		if result.Uri != testPath {
+			t.Errorf("Mismatched uri")
+		}
+		if result.Method != uint32(testMethod) {
+			t.Errorf("Mismatched method")
+		}
+		if !bytes.Equal(testMessage.Content, result.Content) {
+			t.Errorf("Mismatched content")
+		}
+	case <-time.After(3 * time.Second):
+		t.Errorf("Test SingleResponse timed out!")
+	}
+}
+
+// Test proto error path
+func TestSingleResponse_Callback_ProtoErr(t *testing.T) {
+	resultChan := make(chan *restlike.Message, 1)
+	cb := func(input *restlike.Message) {
+		resultChan <- input
+	}
+	r := response{cb}
+
+	r.Hear(receive.Message{Payload: []byte("test")})
+
+	select {
+	case result := <-resultChan:
+		if len(result.Error) == 0 {
+			t.Errorf("Expected cb proto error!")
+		}
+	case <-time.After(3 * time.Second):
+		t.Errorf("Test SingleResponse proto error timed out!")
+	}
+}
diff --git a/restlike/connect/server.go b/restlike/connect/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..977edb7f212781b43f683f2c0f850d00d829344b
--- /dev/null
+++ b/restlike/connect/server.go
@@ -0,0 +1,59 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 Privategrity Corporation                                   /
+//                                                                             /
+// All rights reserved.                                                        /
+////////////////////////////////////////////////////////////////////////////////
+
+package connect
+
+import (
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/cmix"
+	"gitlab.com/elixxir/client/connect"
+	"gitlab.com/elixxir/client/restlike"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/primitives/id"
+)
+
+// Server implements the RestServer interface using connect.Connection
+type Server struct {
+	receptionId *id.ID
+	endpoints   *restlike.Endpoints
+}
+
+// NewServer builds a RestServer with connect.Connection and
+// the provided arguments, then registers necessary external services
+func NewServer(receptionId *id.ID, privKey *cyclic.Int,
+	rng *fastRNG.StreamGenerator, grp *cyclic.Group, net cmix.Client, p connect.Params) (*Server, error) {
+	newServer := &Server{
+		receptionId: receptionId,
+		endpoints:   restlike.NewEndpoints(),
+	}
+
+	// Callback for connection requests
+	cb := func(conn connect.Connection) {
+		handler := receiver{endpoints: newServer.endpoints, conn: conn}
+		conn.RegisterListener(catalog.XxMessage, handler)
+	}
+
+	// Build the connection listener
+	err := connect.StartServer(cb, receptionId, privKey, rng, grp, net, p)
+	if err != nil {
+		return nil, err
+	}
+	return newServer, nil
+}
+
+// GetEndpoints returns the association of a Callback with
+// a specific URI and a variety of different REST Method
+func (c *Server) GetEndpoints() *restlike.Endpoints {
+	return c.endpoints
+}
+
+// Close the internal RestServer endpoints and external services
+func (c *Server) Close() {
+	// Clear all internal endpoints
+	c.endpoints = nil
+	// TODO: Destroy external services
+}
diff --git a/restlike/restServer.go b/restlike/restServer.go
deleted file mode 100644
index dccb13ad3da83850bdd98be9b568dfab5c933102..0000000000000000000000000000000000000000
--- a/restlike/restServer.go
+++ /dev/null
@@ -1,67 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-// Copyright © 2022 Privategrity Corporation                                   /
-//                                                                             /
-// All rights reserved.                                                        /
-////////////////////////////////////////////////////////////////////////////////
-
-package restlike
-
-import (
-	"gitlab.com/elixxir/client/catalog"
-	"gitlab.com/elixxir/client/single"
-	"gitlab.com/elixxir/crypto/cyclic"
-	"gitlab.com/xx_network/primitives/id"
-)
-
-// RestServer allows for clients to make REST-like requests this client
-type RestServer interface {
-	// RegisterEndpoint allows the association of a Callback with
-	// a specific URI and a variety of different REST Method
-	RegisterEndpoint(path URI, method Method, cb Callback) error
-
-	// UnregisterEndpoint removes the Callback associated with
-	// a specific URI and REST Method
-	UnregisterEndpoint(path URI, method Method) error
-
-	// Close the internal RestServer endpoints and external services
-	Close()
-}
-
-// singleServer implements the RestServer interface using single-use
-type singleServer struct {
-	receptionId *id.ID
-	listener    single.Listener
-	endpoints   *Endpoints
-}
-
-// NewSingleServer builds a RestServer with single-use and
-// the provided arguments, then registers necessary external services
-func NewSingleServer(receptionId *id.ID, privKey *cyclic.Int, net single.ListenCmix, e2eGrp *cyclic.Group) RestServer {
-	newServer := &singleServer{
-		receptionId: receptionId,
-		endpoints:   &Endpoints{endpoints: make(map[URI]map[Method]Callback)},
-	}
-	newServer.listener = single.Listen(catalog.RestLike, receptionId, privKey,
-		net, e2eGrp, &singleReceiver{newServer.endpoints})
-	return newServer
-}
-
-// RegisterEndpoint allows the association of a Callback with
-// a specific URI and a variety of different REST Method
-func (r *singleServer) RegisterEndpoint(path URI, method Method, cb Callback) error {
-	return r.endpoints.Add(path, method, cb)
-}
-
-// UnregisterEndpoint removes the Callback associated with
-// a specific URI and REST Method
-func (r *singleServer) UnregisterEndpoint(path URI, method Method) error {
-	return r.endpoints.Remove(path, method)
-}
-
-// Close the internal RestServer endpoints and external services
-func (r *singleServer) Close() {
-	// Clear all internal endpoints
-	r.endpoints = nil
-	// Destroy external services
-	r.listener.Stop()
-}
diff --git a/restlike/singleReceiver.go b/restlike/single/receiver.go
similarity index 63%
rename from restlike/singleReceiver.go
rename to restlike/single/receiver.go
index 7a137631bea709c8b9d7dabbb0888fec60a60cdc..f82a1f327ee9b7215aa20748da044bdc63f464c9 100644
--- a/restlike/singleReceiver.go
+++ b/restlike/single/receiver.go
@@ -4,7 +4,7 @@
 // All rights reserved.                                                        /
 ////////////////////////////////////////////////////////////////////////////////
 
-package restlike
+package single
 
 import (
 	"github.com/pkg/errors"
@@ -12,21 +12,22 @@ import (
 	"gitlab.com/elixxir/client/cmix"
 	"gitlab.com/elixxir/client/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/cmix/rounds"
+	"gitlab.com/elixxir/client/restlike"
 	"gitlab.com/elixxir/client/single"
 	"google.golang.org/protobuf/proto"
 	"time"
 )
 
-// processor is the reception handler for a RestServer
-type singleReceiver struct {
-	endpoints *Endpoints
+// receiver is the reception handler for a RestServer
+type receiver struct {
+	endpoints *restlike.Endpoints
 }
 
 // Callback is the handler for single-use message reception for a RestServer
 // Automatically responds to invalid endpoint requests
-func (s *singleReceiver) Callback(req *single.Request, receptionId receptionID.EphemeralIdentity, rounds []rounds.Round) {
+func (s *receiver) Callback(req *single.Request, receptionId receptionID.EphemeralIdentity, rounds []rounds.Round) {
 	// Unmarshal the request payload
-	newMessage := &Message{}
+	newMessage := &restlike.Message{}
 	err := proto.Unmarshal(req.GetPayload(), newMessage)
 	if err != nil {
 		jww.ERROR.Printf("Unable to unmarshal restlike message: %+v", err)
@@ -34,20 +35,20 @@ func (s *singleReceiver) Callback(req *single.Request, receptionId receptionID.E
 	}
 
 	var respondErr error
-	if cb, err := s.endpoints.Get(URI(newMessage.GetUri()), Method(newMessage.GetMethod())); err == nil {
-		// Send the payload to the proper Callback if it exists and respond with the result
-		respondErr = respond(cb(newMessage), req)
+	if cb, err := s.endpoints.Get(restlike.URI(newMessage.GetUri()), restlike.Method(newMessage.GetMethod())); err == nil {
+		// Send the payload to the proper Callback if it exists and singleRespond with the result
+		respondErr = singleRespond(cb(newMessage), req)
 	} else {
 		// If no callback, automatically send an error response
-		respondErr = respond(&Message{Error: err.Error()}, req)
+		respondErr = singleRespond(&restlike.Message{Error: err.Error()}, req)
 	}
 	if respondErr != nil {
-		jww.ERROR.Printf("Unable to respond to request: %+v", err)
+		jww.ERROR.Printf("Unable to singleRespond to request: %+v", err)
 	}
 }
 
-// respond to a single.Request with the given Message
-func respond(response *Message, req *single.Request) error {
+// singleRespond to a single.Request with the given Message
+func singleRespond(response *restlike.Message, req *single.Request) error {
 	payload, err := proto.Marshal(response)
 	if err != nil {
 		return errors.Errorf("unable to marshal restlike response message: %+v", err)
diff --git a/restlike/singleReceiver_test.go b/restlike/single/receiver_test.go
similarity index 87%
rename from restlike/singleReceiver_test.go
rename to restlike/single/receiver_test.go
index 56a46586daaf6411d589b79c0e179ade2ce4e017..6922991fdb686a7350095fe52462699361953e8c 100644
--- a/restlike/singleReceiver_test.go
+++ b/restlike/single/receiver_test.go
@@ -4,21 +4,22 @@
 // All rights reserved.                                                        /
 ////////////////////////////////////////////////////////////////////////////////
 
-package restlike
+package single
 
 import (
 	"gitlab.com/elixxir/client/cmix/identity/receptionID"
+	"gitlab.com/elixxir/client/restlike"
 	"gitlab.com/elixxir/client/single"
 	"testing"
 )
 
 // Test failure of proto unmarshal
 func TestSingleReceiver_Callback_FailUnmarshal(t *testing.T) {
-	ep := &Endpoints{endpoints: make(map[URI]map[Method]Callback)}
-	receiver := singleReceiver{endpoints: ep}
+	ep := restlike.NewEndpoints()
+	r := receiver{endpoints: ep}
 
 	testReq := single.BuildTestRequest(make([]byte, 0), t)
-	receiver.Callback(testReq, receptionID.EphemeralIdentity{}, nil)
+	r.Callback(testReq, receptionID.EphemeralIdentity{}, nil)
 }
 
 // Test happy path
@@ -43,7 +44,7 @@ func TestSingleReceiver_Callback_FailUnmarshal(t *testing.T) {
 //	if err != nil {
 //		t.Errorf(err.Error())
 //	}
-//	receiver := singleReceiver{endpoints: ep}
+//	receiver := receiver{endpoints: ep}
 //
 //	testPayload, err := proto.Marshal(testMessage)
 //	if err != nil {
diff --git a/restlike/singleRequest.go b/restlike/single/request.go
similarity index 69%
rename from restlike/singleRequest.go
rename to restlike/single/request.go
index 774f112c43745c0a36b9692ceb209bd4e8b783f1..8a0b550867b5d2ebdaa43333fcf529940c701982 100644
--- a/restlike/singleRequest.go
+++ b/restlike/single/request.go
@@ -4,11 +4,12 @@
 // All rights reserved.                                                        /
 ////////////////////////////////////////////////////////////////////////////////
 
-package restlike
+package single
 
 import (
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/restlike"
 	"gitlab.com/elixxir/client/single"
 	"gitlab.com/elixxir/crypto/contact"
 	"gitlab.com/elixxir/crypto/cyclic"
@@ -16,9 +17,9 @@ import (
 	"google.golang.org/protobuf/proto"
 )
 
-// SingleRequest allows for making REST-like requests to a RestServer using single-use messages
+// Request allows for making REST-like requests to a RestServer using single-use messages
 // Can be used as stateful or declared inline without state
-type SingleRequest struct {
+type Request struct {
 	Net    single.Cmix
 	Rng    csprng.Source
 	E2eGrp *cyclic.Group
@@ -26,10 +27,10 @@ type SingleRequest struct {
 
 // Request provides several Method of sending Data to the given URI
 // and blocks until the Message is returned
-func (s *SingleRequest) Request(recipient contact.Contact, method Method, path URI,
-	content Data, headers *Headers, singleParams single.RequestParams) (*Message, error) {
+func (s *Request) Request(recipient contact.Contact, method restlike.Method, path restlike.URI,
+	content restlike.Data, headers *restlike.Headers, singleParams single.RequestParams) (*restlike.Message, error) {
 	// Build the Message
-	newMessage := &Message{
+	newMessage := &restlike.Message{
 		Content: content,
 		Headers: headers,
 		Method:  uint32(method),
@@ -41,14 +42,14 @@ func (s *SingleRequest) Request(recipient contact.Contact, method Method, path U
 	}
 
 	// Build callback for the single-use response
-	signalChannel := make(chan *Message, 1)
-	cb := func(msg *Message) {
+	signalChannel := make(chan *restlike.Message, 1)
+	cb := func(msg *restlike.Message) {
 		signalChannel <- msg
 	}
 
 	// Transmit the Message
 	_, _, err = single.TransmitRequest(recipient, catalog.RestLike, msg,
-		&singleResponse{responseCallback: cb}, singleParams, s.Net, s.Rng, s.E2eGrp)
+		&response{responseCallback: cb}, singleParams, s.Net, s.Rng, s.E2eGrp)
 	if err != nil {
 		return nil, err
 	}
@@ -63,10 +64,10 @@ func (s *SingleRequest) Request(recipient contact.Contact, method Method, path U
 
 // AsyncRequest provides several Method of sending Data to the given URI
 // and will return the Message to the given Callback when received
-func (s *SingleRequest) AsyncRequest(recipient contact.Contact, method Method, path URI,
-	content Data, headers *Headers, cb RequestCallback, singleParams single.RequestParams) error {
+func (s *Request) AsyncRequest(recipient contact.Contact, method restlike.Method, path restlike.URI,
+	content restlike.Data, headers *restlike.Headers, cb restlike.RequestCallback, singleParams single.RequestParams) error {
 	// Build the Message
-	newMessage := &Message{
+	newMessage := &restlike.Message{
 		Content: content,
 		Headers: headers,
 		Method:  uint32(method),
@@ -79,6 +80,6 @@ func (s *SingleRequest) AsyncRequest(recipient contact.Contact, method Method, p
 
 	// Transmit the Message
 	_, _, err = single.TransmitRequest(recipient, catalog.RestLike, msg,
-		&singleResponse{responseCallback: cb}, singleParams, s.Net, s.Rng, s.E2eGrp)
+		&response{responseCallback: cb}, singleParams, s.Net, s.Rng, s.E2eGrp)
 	return err
 }
diff --git a/restlike/singleResponse.go b/restlike/single/response.go
similarity index 74%
rename from restlike/singleResponse.go
rename to restlike/single/response.go
index 41e21b6061c110eaaa06fc25a472bf0326ca1ff3..edc4833226d0372ae6816f4a190772127aaf6e7e 100644
--- a/restlike/singleResponse.go
+++ b/restlike/single/response.go
@@ -4,22 +4,23 @@
 // All rights reserved.                                                        /
 ////////////////////////////////////////////////////////////////////////////////
 
-package restlike
+package single
 
 import (
 	"gitlab.com/elixxir/client/cmix/identity/receptionID"
 	"gitlab.com/elixxir/client/cmix/rounds"
+	"gitlab.com/elixxir/client/restlike"
 	"google.golang.org/protobuf/proto"
 )
 
-// processor is the response handler for a Request
-type singleResponse struct {
-	responseCallback RequestCallback
+// response is the response handler for a Request
+type response struct {
+	responseCallback restlike.RequestCallback
 }
 
 // Callback is the handler for single-use message responses for a Request
-func (s *singleResponse) Callback(payload []byte, receptionID receptionID.EphemeralIdentity, rounds []rounds.Round, err error) {
-	newMessage := &Message{}
+func (s *response) Callback(payload []byte, receptionID receptionID.EphemeralIdentity, rounds []rounds.Round, err error) {
+	newMessage := &restlike.Message{}
 
 	// Handle response errors
 	if err != nil {
diff --git a/restlike/singleResponse_test.go b/restlike/single/response_test.go
similarity index 74%
rename from restlike/singleResponse_test.go
rename to restlike/single/response_test.go
index 0381b452cca26c9d892abfe2b8329569a1eef689..b5e11bf81acca0a91cd9342390b7e712125a4518 100644
--- a/restlike/singleResponse_test.go
+++ b/restlike/single/response_test.go
@@ -4,12 +4,13 @@
 // All rights reserved.                                                        /
 ////////////////////////////////////////////////////////////////////////////////
 
-package restlike
+package single
 
 import (
 	"bytes"
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/cmix/identity/receptionID"
+	"gitlab.com/elixxir/client/restlike"
 	"google.golang.org/protobuf/proto"
 	"testing"
 	"time"
@@ -17,13 +18,13 @@ import (
 
 // Test happy path
 func TestSingleResponse_Callback(t *testing.T) {
-	resultChan := make(chan *Message, 1)
-	cb := func(input *Message) {
+	resultChan := make(chan *restlike.Message, 1)
+	cb := func(input *restlike.Message) {
 		resultChan <- input
 	}
 	testPath := "test/path"
-	testMethod := Get
-	testMessage := &Message{
+	testMethod := restlike.Get
+	testMessage := &restlike.Message{
 		Content: []byte("test"),
 		Headers: nil,
 		Method:  uint32(testMethod),
@@ -31,13 +32,13 @@ func TestSingleResponse_Callback(t *testing.T) {
 		Error:   "",
 	}
 
-	response := singleResponse{cb}
+	r := response{cb}
 
 	testPayload, err := proto.Marshal(testMessage)
 	if err != nil {
 		t.Errorf(err.Error())
 	}
-	response.Callback(testPayload, receptionID.EphemeralIdentity{}, nil, nil)
+	r.Callback(testPayload, receptionID.EphemeralIdentity{}, nil, nil)
 
 	select {
 	case result := <-resultChan:
@@ -57,13 +58,13 @@ func TestSingleResponse_Callback(t *testing.T) {
 
 // Test error input path
 func TestSingleResponse_Callback_Err(t *testing.T) {
-	resultChan := make(chan *Message, 1)
-	cb := func(input *Message) {
+	resultChan := make(chan *restlike.Message, 1)
+	cb := func(input *restlike.Message) {
 		resultChan <- input
 	}
-	response := singleResponse{cb}
+	r := response{cb}
 
-	response.Callback(nil, receptionID.EphemeralIdentity{}, nil, errors.New("test"))
+	r.Callback(nil, receptionID.EphemeralIdentity{}, nil, errors.New("test"))
 
 	select {
 	case result := <-resultChan:
@@ -77,13 +78,13 @@ func TestSingleResponse_Callback_Err(t *testing.T) {
 
 // Test proto error path
 func TestSingleResponse_Callback_ProtoErr(t *testing.T) {
-	resultChan := make(chan *Message, 1)
-	cb := func(input *Message) {
+	resultChan := make(chan *restlike.Message, 1)
+	cb := func(input *restlike.Message) {
 		resultChan <- input
 	}
-	response := singleResponse{cb}
+	r := response{cb}
 
-	response.Callback([]byte("test"), receptionID.EphemeralIdentity{}, nil, nil)
+	r.Callback([]byte("test"), receptionID.EphemeralIdentity{}, nil, nil)
 
 	select {
 	case result := <-resultChan:
diff --git a/restlike/single/server.go b/restlike/single/server.go
new file mode 100644
index 0000000000000000000000000000000000000000..b5bbbd4ee8dc14f58e4dddbfdc356c6b33582d5c
--- /dev/null
+++ b/restlike/single/server.go
@@ -0,0 +1,48 @@
+////////////////////////////////////////////////////////////////////////////////
+// Copyright © 2022 Privategrity Corporation                                   /
+//                                                                             /
+// All rights reserved.                                                        /
+////////////////////////////////////////////////////////////////////////////////
+
+package single
+
+import (
+	"gitlab.com/elixxir/client/catalog"
+	"gitlab.com/elixxir/client/restlike"
+	"gitlab.com/elixxir/client/single"
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/xx_network/primitives/id"
+)
+
+// Server implements the RestServer interface using single-use
+type Server struct {
+	receptionId *id.ID
+	listener    single.Listener
+	endpoints   *restlike.Endpoints
+}
+
+// NewServer builds a RestServer with single-use and
+// the provided arguments, then registers necessary external services
+func NewServer(receptionId *id.ID, privKey *cyclic.Int, net single.ListenCmix, e2eGrp *cyclic.Group) *Server {
+	newServer := &Server{
+		receptionId: receptionId,
+		endpoints:   restlike.NewEndpoints(),
+	}
+	newServer.listener = single.Listen(catalog.RestLike, receptionId, privKey,
+		net, e2eGrp, &receiver{newServer.endpoints})
+	return newServer
+}
+
+// GetEndpoints returns the association of a Callback with
+// a specific URI and a variety of different REST Method
+func (r *Server) GetEndpoints() *restlike.Endpoints {
+	return r.endpoints
+}
+
+// Close the internal RestServer endpoints and external services
+func (r *Server) Close() {
+	// Clear all internal endpoints
+	r.endpoints = nil
+	// Destroy external services
+	r.listener.Stop()
+}
diff --git a/restlike/types.go b/restlike/types.go
index 247943844613a43c99b5d666f412a5c53f078471..8937575ed720bb14634bf34e6d02908988a28b13 100644
--- a/restlike/types.go
+++ b/restlike/types.go
@@ -68,6 +68,11 @@ type Endpoints struct {
 	sync.RWMutex
 }
 
+// NewEndpoints returns a new Endpoints object
+func NewEndpoints() *Endpoints {
+	return &Endpoints{endpoints: make(map[URI]map[Method]Callback)}
+}
+
 // Add a new Endpoint
 // Returns an error if Endpoint already exists
 func (e *Endpoints) Add(path URI, method Method, cb Callback) error {