diff --git a/connect/host.go b/connect/host.go
index b388b04a15dfe0add28bd93a0e81ab0e3b531833..22b02e8c97ebe3bb6f2b4c81fe42f80d547a5447 100644
--- a/connect/host.go
+++ b/connect/host.go
@@ -116,6 +116,11 @@ func (h *Host) IsDynamicHost() bool {
 	return h.dynamicHost
 }
 
+// Simple getter for the public key
+func (h *Host) GetPubKey() *rsa.PublicKey {
+	return h.rsaPublicKey
+}
+
 // Connected checks if the given Host's connection is alive
 func (h *Host) Connected() bool {
 	h.mux.RLock()
diff --git a/network/dataStructures/ndf.go b/network/dataStructures/ndf.go
index ea2c7c4a4cfccc8c18ac25e69927a3326fda746d..75f305d678df5b542cce13feb4a74abb294ac9aa 100644
--- a/network/dataStructures/ndf.go
+++ b/network/dataStructures/ndf.go
@@ -1,11 +1,97 @@
 package dataStructures
 
-import "gitlab.com/elixxir/primitives/ndf"
+import (
+	"bytes"
+	"crypto/sha256"
+	"github.com/pkg/errors"
+	pb "gitlab.com/elixxir/comms/mixmessages"
+	"gitlab.com/elixxir/primitives/ndf"
+	"sync"
+)
 
 type Ndf struct{
-	f ndf.NetworkDefinition
+	f *ndf.NetworkDefinition
+	pb *pb.NDF
 	hash []byte
+	lock sync.RWMutex
 }
 
+//Updates to a new NDF if the passed NDF is valid
+func(file *Ndf)Update(m *pb.NDF)error{
+
+	//build the ndf object
+	decoded, _, err := ndf.DecodeNDF(string(m.Ndf))
+
+	if err!=nil{
+		return errors.WithMessage(err,"Could not decode the NDF")
+	}
+
+	file.lock.Lock()
+	defer file.lock.Unlock()
+
+	file.pb = m
+	file.f = decoded
+
+	//set the ndf hash
+	marshaled, err := file.f.Marshal()
+	if err != nil {
+		return errors.WithMessage(err,
+			"Could not marshal NDF for hashing")
+	}
+
+	// Serialize then hash the constructed ndf
+	hash := sha256.New()
+	hash.Write(marshaled)
+	file.hash = hash.Sum(nil)
+
+	return nil
+}
+
+//returns the ndf object
+//fix-me: return a copy instead to ensure edits to not impact the
+//original version
+func(file *Ndf)Get()*ndf.NetworkDefinition{
+	file.lock.RLock()
+	defer file.lock.RUnlock()
+	return file.f
+}
+
+//returns the ndf hash
+func(file *Ndf)GetHash()[]byte{
+	file.lock.RLock()
+	defer file.lock.RUnlock()
+	rtn := make([]byte, len(file.hash))
+	copy(rtn,file.hash)
+	return rtn
+}
+
+//returns the ndf hash
+//fix-me: return a copy instead to ensure edits to not impact the
+//original version
+func(file *Ndf)GetPb()*pb.NDF{
+	file.lock.RLock()
+	defer file.lock.RUnlock()
+	return file.pb
+}
+
+//evaluates if the passed ndf hash is the same as the stored one
+//returns an error if no ndf is available, returns false if they are different
+//and true if they are the same
+func(file *Ndf)CompareHash(h []byte)(bool, error){
+	file.lock.RLock()
+	defer file.lock.RUnlock()
+	//return the NO_NDF error if no NDF is available
+	if len(file.hash) == 0 {
+		errMsg := errors.Errorf(ndf.NO_NDF)
+		return false, errMsg
+	}
+
+	//return true if the hashes are the same
+	if bytes.Compare(file.hash, h) == 0 {
+		return true, nil
+	}
+
+	//return false if the hashes are different
+	return false, nil
+}
 
-func(ndf *Ndf)Update(
diff --git a/network/dataStructures/roundData_test.go b/network/dataStructures/roundData_test.go
index 6d2cb10ff31ff5bf5300f4903199a73763b6e78c..54e17276e965d26ed01c6ba939b275554ce99cd9 100644
--- a/network/dataStructures/roundData_test.go
+++ b/network/dataStructures/roundData_test.go
@@ -1 +1,29 @@
 package dataStructures
+
+import (
+	"gitlab.com/elixxir/comms/mixmessages"
+	"testing"
+)
+
+func TestData_UpsertRound(t *testing.T) {
+	d := Data{}
+	err := d.UpsertRound(&mixmessages.RoundInfo{
+		ID:       0,
+		UpdateID: 0,
+	})
+	if err != nil {
+		t.Errorf("Failed to upsert round: %+v", err)
+	}
+}
+
+func TestData_GetRound(t *testing.T) {
+	d := Data{}
+	_ = d.UpsertRound(&mixmessages.RoundInfo{
+		ID:       0,
+		UpdateID: 3,
+	})
+	_, err := d.GetRound(0)
+	if err != nil {
+		t.Errorf("Failed to get roundinfo with proper id")
+	}
+}
diff --git a/network/dataStructures/roundUpdates_test.go b/network/dataStructures/roundUpdates_test.go
index 6ff5f52fb1978b0a97dacfdc2433a48f158569c8..a1b1dafdc0f33567bf7ed463d5329736316997ba 100644
--- a/network/dataStructures/roundUpdates_test.go
+++ b/network/dataStructures/roundUpdates_test.go
@@ -5,29 +5,6 @@ import (
 	"testing"
 )
 
-func TestData_UpsertRound(t *testing.T) {
-	d := Data{}
-	err := d.UpsertRound(&mixmessages.RoundInfo{
-		ID:       0,
-		UpdateID: 0,
-	})
-	if err != nil {
-		t.Errorf("Failed to upsert round: %+v", err)
-	}
-}
-
-func TestData_GetRound(t *testing.T) {
-	d := Data{}
-	_ = d.UpsertRound(&mixmessages.RoundInfo{
-		ID:       0,
-		UpdateID: 3,
-	})
-	_, err := d.GetRound(0)
-	if err != nil {
-		t.Errorf("Failed to get roundinfo with proper id")
-	}
-}
-
 func TestUpdates_AddRound(t *testing.T) {
 	u := Updates{}
 	err := u.AddRound(&mixmessages.RoundInfo{
diff --git a/network/instance.go b/network/instance.go
new file mode 100644
index 0000000000000000000000000000000000000000..55cbe90fc2dd8f3fe6a58e0f328e7d5d61ad5c25
--- /dev/null
+++ b/network/instance.go
@@ -0,0 +1,108 @@
+package network
+
+import(
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/comms/connect"
+	ds "gitlab.com/elixxir/comms/network/dataStructures"
+	pb "gitlab.com/elixxir/comms/mixmessages"
+	"gitlab.com/elixxir/crypto/signature"
+	"gitlab.com/elixxir/primitives/id"
+	"sync"
+)
+
+type Instance struct {
+	comm *connect.ProtoComms
+
+	partial *SecuredNdf
+	full *SecuredNdf
+	roundUpdates *ds.Updates
+	roundData *ds.Data
+
+	roundlock sync.RWMutex
+}
+
+
+func NewInstance(c *connect.ProtoComms)*Instance{
+	return &Instance{
+		c,
+		NewSecuredNdf(),
+		NewSecuredNdf(),
+		&ds.Updates{},
+		&ds.Data{},
+		sync.RWMutex{},
+	}
+}
+
+//update the partial ndf
+func (i *Instance)UpdatePartialNdf(m *pb.NDF)error{
+	perm, success := i.comm.GetHost(id.PERMISSIONING)
+
+	if !success{
+		return errors.New("Could not get permissioning Public Key" +
+			"for NDF partial verification")
+	}
+
+	return i.partial.update(m,perm.GetPubKey())
+}
+
+//update the full ndf
+func (i *Instance)UpdateFullNdf(m *pb.NDF)error{
+	perm, success := i.comm.GetHost(id.PERMISSIONING)
+
+	if !success{
+		return errors.New("Could not get permissioning Public Key" +
+			"for full NDF verification")
+	}
+
+	return i.full.update(m,perm.GetPubKey())
+}
+
+func (i *Instance)GetPartialNdf()*SecuredNdf{
+	return i.partial
+}
+
+func (i *Instance)GetFullNdf()*SecuredNdf{
+	return i.full
+}
+
+func (i *Instance)RoundUpdate(info *pb.RoundInfo)error{
+	perm, success := i.comm.GetHost(id.PERMISSIONING)
+
+	if !success{
+		return errors.New("Could not get permissioning Public Key" +
+			"for round info verification")
+	}
+
+	err := signature.Verify(info, perm.GetPubKey())
+	if err!=nil{
+		return errors.WithMessage(err, "Could not validate NDF")
+	}
+
+	i.roundlock.Lock()
+	defer i.roundlock.Unlock()
+
+	err = i.roundUpdates.AddRound(info)
+	if err!=nil{
+		return err
+	}
+
+	err = i.roundData.UpsertRound(info)
+	if err!=nil{
+		return err
+	}
+
+	return nil
+}
+
+func (i *Instance)GetRound(id id.Round)(*pb.RoundInfo, error){
+	return i.roundData.GetRound(int(id))
+}
+
+func (i *Instance)GetRoundUpdate(updateID int)(*pb.RoundInfo, error){
+	return i.roundUpdates.GetUpdate(updateID)
+}
+
+func (i *Instance)GetRoundUpdates(id id.Round)([]*pb.RoundInfo, error){
+	return nil, nil
+}
+
diff --git a/network/securedNdf.go b/network/securedNdf.go
new file mode 100644
index 0000000000000000000000000000000000000000..bcc92a673736531f37c4c23ee60a6d3a87ff867f
--- /dev/null
+++ b/network/securedNdf.go
@@ -0,0 +1,49 @@
+package network
+
+import(
+	"github.com/pkg/errors"
+	ds "gitlab.com/elixxir/comms/network/dataStructures"
+	"gitlab.com/elixxir/crypto/signature"
+	"gitlab.com/elixxir/crypto/signature/rsa"
+	pb "gitlab.com/elixxir/comms/mixmessages"
+	"gitlab.com/elixxir/primitives/ndf"
+)
+
+// wraps the ndf data structure, expoting all the functionality expect the
+// ability to change the ndf
+type SecuredNdf struct{
+	f *ds.Ndf
+}
+
+func NewSecuredNdf()*SecuredNdf{
+	return &SecuredNdf{
+		&ds.Ndf{},
+	}
+}
+
+// unexported NDF update code
+func (sndf *SecuredNdf)update(m *pb.NDF, key *rsa.PublicKey)error{
+	err := signature.Verify(m, key)
+	if err!=nil{
+		return errors.WithMessage(err, "Could not validate NDF")
+	}
+
+	return sndf.f.Update(m)
+}
+
+func (sndf *SecuredNdf)Get()*ndf.NetworkDefinition{
+	return sndf.f.Get()
+}
+
+func (sndf *SecuredNdf)GetHash()[]byte{
+	return sndf.f.GetHash()
+}
+
+func (sndf *SecuredNdf)GetPb()*pb.NDF{
+	return sndf.f.GetPb()
+}
+
+func(sndf *SecuredNdf)CompareHash(h []byte)(bool, error) {
+	return sndf.f.CompareHash(h)
+}
+
diff --git a/network/securedNdf_test.go b/network/securedNdf_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..20972f9acb1eb104802d1ca1b3695fa2caa7dba4
--- /dev/null
+++ b/network/securedNdf_test.go
@@ -0,0 +1,14 @@
+package network
+
+import "testing"
+
+func TestNewSecuredNdf(t *testing.T) {
+	sndf := NewSecuredNdf()
+	if sndf==nil{
+		t.Errorf("Internal ndf object is nil")
+	}
+}
+
+func TestSecuredNdf_CompareHash(t *testing.T) {
+
+}
\ No newline at end of file