diff --git a/README.md b/README.md
index a2269de11b75c28de5da068eef61e313fc7366bd..0fa75799f1fe7a64ac712daa25bdf82e2a9a68de 100644
--- a/README.md
+++ b/README.md
@@ -4,6 +4,7 @@
 [![coverage report](https://gitlab.com/xx_network/comms/badges/master/coverage.svg)](https://gitlab.com/xx_network/comms/commits/master)
 
 ```
+protoc -I interconnect/ interconnect/interconnect.proto -I /path/to/gitlab.com/ --go_out=plugins=grpc:interconnect
 protoc -I messages/ messages/messages.proto --go_out=plugins=grpc:messages
 protoc -I gossip/ gossip/messages.proto --go_out=plugins=grpc:gossip
 ```
diff --git a/connect/comms_test.go b/connect/comms_test.go
index ee1eb5fcd495d9cb8f86bd2da4da7ec44d9bf98d..95f543f6fd7744bf2f33bfa35cba2e912ee93ab1 100644
--- a/connect/comms_test.go
+++ b/connect/comms_test.go
@@ -34,4 +34,4 @@ func TestSendNoAddressFails(t *testing.T) {
 	if err.Error() != "Host address is blank, host might be receive only." {
 		t.Errorf("Send function should have errored with address error.")
 	}
-}
\ No newline at end of file
+}
diff --git a/go.mod b/go.mod
index 15b8bcf0722d8df9a4e7e919cd500b4a4288e6ea..0ecd723e5994f651d553509ff6aa1af569679699 100644
--- a/go.mod
+++ b/go.mod
@@ -8,7 +8,7 @@ require (
 	github.com/spf13/jwalterweatherman v1.1.0
 	github.com/zeebo/blake3 v0.0.4
 	gitlab.com/elixxir/comms v0.0.0-20200707210150-b8ebd0951d23
-	gitlab.com/elixxir/crypto v0.0.0-20200707005343-97f868cbd930
+	gitlab.com/elixxir/crypto v0.0.0-20200803223738-661ca14b6470
 	gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d
 	golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9
 	golang.org/x/net v0.0.0-20200707034311-ab3426394381
diff --git a/go.sum b/go.sum
index 9304ebd5a8821a8f8e0a59514a7010715b430bd2..6e81c6e37e5374d945667b27974e2ffe880416e6 100644
--- a/go.sum
+++ b/go.sum
@@ -61,6 +61,8 @@ gitlab.com/elixxir/comms v0.0.0-20200707210150-b8ebd0951d23 h1:ikyf3DPibZq+SsVUe
 gitlab.com/elixxir/comms v0.0.0-20200707210150-b8ebd0951d23/go.mod h1:OsWMZ1O/R9fOkm+PoHnR3rkXfFtipGoPs73FuKuurHY=
 gitlab.com/elixxir/crypto v0.0.0-20200707005343-97f868cbd930 h1:9qzfwyR12OYgn3j30qcHZHHVfWshWnH54lcAHppEROQ=
 gitlab.com/elixxir/crypto v0.0.0-20200707005343-97f868cbd930/go.mod h1:LHBAaEf48a0/AjU118rjoworH0LgXifhAqmNX3ZRvME=
+gitlab.com/elixxir/crypto v0.0.0-20200803223738-661ca14b6470 h1:WGECBA9PtyUk9RfkpHjcbySoXfByEBTaD5IUHmjGem4=
+gitlab.com/elixxir/crypto v0.0.0-20200803223738-661ca14b6470/go.mod h1:LHBAaEf48a0/AjU118rjoworH0LgXifhAqmNX3ZRvME=
 gitlab.com/elixxir/primitives v0.0.0-20200706165052-9fe7a4fb99a3 h1:GTfflZBNLeBq3UApYog0J3+hytdkoRsDduGQji2wyEU=
 gitlab.com/elixxir/primitives v0.0.0-20200706165052-9fe7a4fb99a3/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
 gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d h1:OKWTmYN5q8XVHo8JXThIH0TCuvl/fLXR7MGVacpqfRg=
diff --git a/interconnect/consensusClient.go b/interconnect/consensusClient.go
new file mode 100644
index 0000000000000000000000000000000000000000..ef735a322b9e85efbd20bff9d63c6e3be6e27720
--- /dev/null
+++ b/interconnect/consensusClient.go
@@ -0,0 +1,48 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+package interconnect
+
+import (
+	"errors"
+	"github.com/golang/protobuf/ptypes"
+	"github.com/golang/protobuf/ptypes/any"
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/xx_network/comms/connect"
+	"gitlab.com/xx_network/comms/messages"
+	"google.golang.org/grpc"
+)
+
+// consensus Server -> cmix Server Send Function
+func (s *Comms) SendGetNDF(host *connect.Host,
+	message *messages.Ping) (*NDF, error) {
+
+	// Create the Send Function
+	f := func(conn *grpc.ClientConn) (*any.Any, error) {
+		// Set up the context
+		ctx, cancel := connect.MessagingContext()
+		defer cancel()
+		//Format to authenticated message type
+		// Send the message
+
+		resultMsg, err := NewInterconnectClient(conn).GetNDF(ctx, message)
+		if err != nil {
+			return nil, errors.New(err.Error())
+		}
+		return ptypes.MarshalAny(resultMsg)
+	}
+
+	// Execute the Send function
+	jww.DEBUG.Printf("Sending Post Phase message: %+v", message)
+	resultMsg, err := s.Send(host, f)
+	if err != nil {
+		return nil, err
+	}
+
+	// Marshall the result
+	result := &NDF{}
+	return result, ptypes.UnmarshalAny(resultMsg, result)
+}
diff --git a/interconnect/consensusClient_test.go b/interconnect/consensusClient_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..3728c1cdc075d806a6fffcf53296af9fbc644fa8
--- /dev/null
+++ b/interconnect/consensusClient_test.go
@@ -0,0 +1,38 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+package interconnect
+
+import (
+	"bytes"
+	"context"
+	"gitlab.com/elixxir/primitives/id"
+	"gitlab.com/xx_network/comms/messages"
+	"gitlab.com/xx_network/comms/testkeys"
+	"testing"
+)
+
+func TestComms_SendGetNDF(t *testing.T) {
+	testNodeID := id.NewIdFromString("test", id.Node, t)
+	testPort := "5959"
+
+	certPEM := testkeys.LoadFromPath(testkeys.GetNodeCertPath())
+	keyPEM := testkeys.LoadFromPath(testkeys.GetNodeKeyPath())
+
+	ic := StartCMixInterconnect(testNodeID, testPort, NewImplementation(), certPEM, keyPEM)
+
+	expectedMessage := []byte("hello world")
+
+	resultMsg, err := ic.GetNDF(context.Background(), &messages.Ping{})
+	if err != nil {
+		t.Errorf("Failed to send message: %v", err)
+	}
+	if !bytes.Equal(expectedMessage, resultMsg.Ndf) {
+		t.Errorf("Unexpected message. "+
+			"\nReceived: %v"+
+			"\nExpected: %v", resultMsg.Ndf, expectedMessage)
+	}
+}
diff --git a/interconnect/endpoints.go b/interconnect/endpoints.go
new file mode 100644
index 0000000000000000000000000000000000000000..df8bc60c497578a040f99785d826537a4942f5a0
--- /dev/null
+++ b/interconnect/endpoints.go
@@ -0,0 +1,19 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+// Endpoints for the interconnect service
+
+package interconnect
+
+import (
+	"context"
+	"gitlab.com/xx_network/comms/messages"
+)
+
+func (c *Comms) GetNDF(ctx context.Context, ping *messages.Ping) (*NDF, error) {
+	return c.handler.GetNDF()
+}
diff --git a/interconnect/handler.go b/interconnect/handler.go
new file mode 100644
index 0000000000000000000000000000000000000000..e29965bc06deaa2d6590040bd12c295389e70e14
--- /dev/null
+++ b/interconnect/handler.go
@@ -0,0 +1,103 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+package interconnect
+
+import (
+	"errors"
+	jww "github.com/spf13/jwalterweatherman"
+	"gitlab.com/elixxir/primitives/id"
+	"gitlab.com/xx_network/comms/connect"
+	"google.golang.org/grpc/reflection"
+	"net"
+	"runtime/debug"
+)
+
+// Starts a new server on the localHost:port specified by port
+// and a callback interface for interconnect operations
+// with given path to public and private key for TLS connection
+func StartCMixInterconnect(id *id.ID, port string, handler Handler,
+	certPEMblock, keyPEMblock []byte) *Comms {
+
+	addr := net.JoinHostPort("0.0.0.0", port)
+
+	pc, lis, err := connect.StartCommServer(id, addr,
+		certPEMblock, keyPEMblock)
+	if err != nil {
+		jww.FATAL.Panicf("Unable to start comms server: %+v", err)
+	}
+
+	CMixInterconnect := Comms{
+		ProtoComms: pc,
+		handler:    handler,
+	}
+
+	go func() {
+		// Register GRPC services to the listening address
+		RegisterInterconnectServer(CMixInterconnect.LocalServer, &CMixInterconnect)
+		//messages.RegisterGenericServer(CMixInterconnect.LocalServer, &CMixInterconnect)
+
+		// Register reflection service on gRPC server.
+		reflection.Register(CMixInterconnect.LocalServer)
+		if err := CMixInterconnect.LocalServer.Serve(lis); err != nil {
+			jww.FATAL.Panicf("Failed to serve: %+v",
+				errors.New(err.Error()))
+		}
+		jww.INFO.Printf("Shutting down node server listener: %s", lis)
+	}()
+
+	return &CMixInterconnect
+
+}
+
+// Server object used to implement endpoints and top-level comms functionality
+type Comms struct {
+	*connect.ProtoComms
+	handler Handler
+}
+
+type Handler interface {
+	// Interconnect interface for getting the NDF
+	GetNDF() (*NDF, error)
+}
+
+type implementationFunctions struct {
+	GetNDF func() (*NDF, error)
+}
+
+// Implementation allows users of the client library to set the
+// functions that implement the node functions
+type Implementation struct {
+	Functions implementationFunctions
+}
+
+// Below is the Implementation implementation, which calls the
+// function matching the variable in the structure.
+
+// NewImplementation returns a Implementation struct with all of the
+// function pointers returning nothing and printing an error.
+func NewImplementation() *Implementation {
+	um := "UNIMPLEMENTED FUNCTION!"
+	warn := func(msg string) {
+		jww.WARN.Printf(msg)
+		jww.WARN.Printf("%s", debug.Stack())
+	}
+	return &Implementation{
+		Functions: implementationFunctions{
+			GetNDF: func() (*NDF, error) {
+				warn(um)
+				return &NDF{
+					Ndf: []byte("hello world"),
+				}, nil
+			},
+		},
+	}
+}
+
+// Interconnect Interface for getting an NDF
+func (s *Implementation) GetNDF() (*NDF, error) {
+	return s.Functions.GetNDF()
+}
diff --git a/interconnect/interconnect.pb.go b/interconnect/interconnect.pb.go
new file mode 100644
index 0000000000000000000000000000000000000000..0ff2fc4d19ae97628f4db41e7f31608d976f98aa
--- /dev/null
+++ b/interconnect/interconnect.pb.go
@@ -0,0 +1,167 @@
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: interconnect.proto
+
+package interconnect
+
+import (
+	context "context"
+	fmt "fmt"
+	proto "github.com/golang/protobuf/proto"
+	messages "gitlab.com/xx_network/comms/messages"
+	grpc "google.golang.org/grpc"
+	codes "google.golang.org/grpc/codes"
+	status "google.golang.org/grpc/status"
+	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.ProtoPackageIsVersion3 // please upgrade the proto package
+
+// The Network Definition File is defined as a
+// JSON structure in primitives/ndf.
+type NDF struct {
+	Ndf                  []byte   `protobuf:"bytes,1,opt,name=Ndf,proto3" json:"Ndf,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *NDF) Reset()         { *m = NDF{} }
+func (m *NDF) String() string { return proto.CompactTextString(m) }
+func (*NDF) ProtoMessage()    {}
+func (*NDF) Descriptor() ([]byte, []int) {
+	return fileDescriptor_076c6e9f11b66192, []int{0}
+}
+
+func (m *NDF) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_NDF.Unmarshal(m, b)
+}
+func (m *NDF) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_NDF.Marshal(b, m, deterministic)
+}
+func (m *NDF) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NDF.Merge(m, src)
+}
+func (m *NDF) XXX_Size() int {
+	return xxx_messageInfo_NDF.Size(m)
+}
+func (m *NDF) XXX_DiscardUnknown() {
+	xxx_messageInfo_NDF.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NDF proto.InternalMessageInfo
+
+func (m *NDF) GetNdf() []byte {
+	if m != nil {
+		return m.Ndf
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterType((*NDF)(nil), "interconnect.NDF")
+}
+
+func init() { proto.RegisterFile("interconnect.proto", fileDescriptor_076c6e9f11b66192) }
+
+var fileDescriptor_076c6e9f11b66192 = []byte{
+	// 150 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x12, 0xca, 0xcc, 0x2b, 0x49,
+	0x2d, 0x4a, 0xce, 0xcf, 0xcb, 0x4b, 0x4d, 0x2e, 0xd1, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2,
+	0x41, 0x16, 0x93, 0x32, 0x4e, 0xcf, 0x2c, 0xc9, 0x49, 0x4c, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0xaf,
+	0xa8, 0x88, 0xcf, 0x4b, 0x2d, 0x29, 0xcf, 0x2f, 0xca, 0xd6, 0x4f, 0xce, 0xcf, 0xcd, 0x2d, 0xd6,
+	0xcf, 0x4d, 0x2d, 0x2e, 0x4e, 0x4c, 0x4f, 0x45, 0x30, 0x20, 0x46, 0x28, 0x89, 0x73, 0x31, 0xfb,
+	0xb9, 0xb8, 0x09, 0x09, 0x70, 0x31, 0xfb, 0xa5, 0xa4, 0x49, 0x30, 0x2a, 0x30, 0x6a, 0xf0, 0x04,
+	0x81, 0x98, 0x46, 0xd6, 0x5c, 0x3c, 0x9e, 0x48, 0xa6, 0x0b, 0x69, 0x73, 0xb1, 0xb9, 0xa7, 0x96,
+	0x80, 0xd4, 0xf2, 0xe9, 0xc1, 0xcd, 0x08, 0xc8, 0xcc, 0x4b, 0x97, 0x12, 0xd4, 0x43, 0x71, 0x9a,
+	0x9f, 0x8b, 0x5b, 0x12, 0x1b, 0xd8, 0x70, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x2e,
+	0x36, 0xe8, 0xb5, 0x00, 0x00, 0x00,
+}
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ context.Context
+var _ grpc.ClientConn
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the grpc package it is being compiled against.
+const _ = grpc.SupportPackageIsVersion4
+
+// InterconnectClient is the client API for Interconnect service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
+type InterconnectClient interface {
+	GetNDF(ctx context.Context, in *messages.Ping, opts ...grpc.CallOption) (*NDF, error)
+}
+
+type interconnectClient struct {
+	cc *grpc.ClientConn
+}
+
+func NewInterconnectClient(cc *grpc.ClientConn) InterconnectClient {
+	return &interconnectClient{cc}
+}
+
+func (c *interconnectClient) GetNDF(ctx context.Context, in *messages.Ping, opts ...grpc.CallOption) (*NDF, error) {
+	out := new(NDF)
+	err := c.cc.Invoke(ctx, "/interconnect.Interconnect/GetNDF", in, out, opts...)
+	if err != nil {
+		return nil, err
+	}
+	return out, nil
+}
+
+// InterconnectServer is the server API for Interconnect service.
+type InterconnectServer interface {
+	GetNDF(context.Context, *messages.Ping) (*NDF, error)
+}
+
+// UnimplementedInterconnectServer can be embedded to have forward compatible implementations.
+type UnimplementedInterconnectServer struct {
+}
+
+func (*UnimplementedInterconnectServer) GetNDF(ctx context.Context, req *messages.Ping) (*NDF, error) {
+	return nil, status.Errorf(codes.Unimplemented, "method GetNDF not implemented")
+}
+
+func RegisterInterconnectServer(s *grpc.Server, srv InterconnectServer) {
+	s.RegisterService(&_Interconnect_serviceDesc, srv)
+}
+
+func _Interconnect_GetNDF_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+	in := new(messages.Ping)
+	if err := dec(in); err != nil {
+		return nil, err
+	}
+	if interceptor == nil {
+		return srv.(InterconnectServer).GetNDF(ctx, in)
+	}
+	info := &grpc.UnaryServerInfo{
+		Server:     srv,
+		FullMethod: "/interconnect.Interconnect/GetNDF",
+	}
+	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+		return srv.(InterconnectServer).GetNDF(ctx, req.(*messages.Ping))
+	}
+	return interceptor(ctx, in, info, handler)
+}
+
+var _Interconnect_serviceDesc = grpc.ServiceDesc{
+	ServiceName: "interconnect.Interconnect",
+	HandlerType: (*InterconnectServer)(nil),
+	Methods: []grpc.MethodDesc{
+		{
+			MethodName: "GetNDF",
+			Handler:    _Interconnect_GetNDF_Handler,
+		},
+	},
+	Streams:  []grpc.StreamDesc{},
+	Metadata: "interconnect.proto",
+}
diff --git a/interconnect/interconnect.proto b/interconnect/interconnect.proto
new file mode 100644
index 0000000000000000000000000000000000000000..3488d81722949c7dbf76050b71efc7ee266b3e07
--- /dev/null
+++ b/interconnect/interconnect.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";
+import "gitlab.com/xx_network/comms/messages/messages.proto";
+
+package interconnect;
+
+// RPC for handling communication between cmix nodes and consensus nodes
+service Interconnect {
+    rpc GetNDF (messages.Ping) returns (NDF);
+}
+
+// The Network Definition File is defined as a
+// JSON structure in primitives/ndf.
+message NDF {
+    bytes Ndf = 1;
+}