diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index da26fe7a0da14e705c49f6f39443403fbbd58710..0c21d1cb36044213f75594a687aaf9a45e32ca65 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -6,12 +6,6 @@ cache:
   paths:
     - vendor/
 
-variables:
-  REPO_DIR: gitlab.com/elixxir
-  REPO_NAME: primitives
-  DOCKER_IMAGE: elixxirlabs/cuda-go:latest
-  MIN_CODE_COVERAGE: "80.0"
-
 before_script:
   - go version || echo "Go executable not found."
   - echo $CI_BUILD_REF
@@ -21,10 +15,10 @@ before_script:
   - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add - > /dev/null
   - mkdir -p ~/.ssh
   - chmod 700 ~/.ssh
-  - ssh-keyscan -t rsa gitlab.com > ~/.ssh/known_hosts
-  - git config --global url."git@gitlab.com:".insteadOf "https://gitlab.com/"
+  - ssh-keyscan -t rsa $GITLAB_SERVER > ~/.ssh/known_hosts
+  - git config --global url."git@$GITLAB_SERVER:".insteadOf "https://gitlab.com/"
   - export PATH=$HOME/go/bin:$PATH
-  - export GOPRIVATE=gitlab.com/elixxir/*
+  - export GOPRIVATE=gitlab.com/elixxir/*,gitlab.com/xx_network/*
 
 stages:
   - build
@@ -32,7 +26,7 @@ stages:
 
 build:
   stage: build
-  image: $DOCKER_IMAGE
+  image: elixxirlabs/cuda-go:go1.13-cuda11.1
   script:
     - git clean -ffdx
     - go mod vendor -v
@@ -58,12 +52,11 @@ build:
       - testdata/
       - release/
 
-trigger:
+trigger_integration:
   stage: trigger_integration
-  script:
-    # client
-    - "curl -X POST -F token=$CLIENT_TRIGGER_KEY -F ref=master https://gitlab.com/api/v4/projects/5454785/trigger/pipeline"
-    # server
-    - "curl -X POST -F token=$SERVER_TRIGGER_KEY -F ref=master https://gitlab.com/api/v4/projects/5014439/trigger/pipeline"
+  trigger:
+    project: elixxir/integration
+    branch: $CI_COMMIT_REF_NAME
   only:
+    - release
     - master
diff --git a/go.sum b/go.sum
index 6bf2385ce6a45d88569e7289b3f385572ec07d47..416d5ffcf1845025c8218c01a71ed28ef09882d0 100644
--- a/go.sum
+++ b/go.sum
@@ -30,9 +30,11 @@ github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
 github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
 github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
 github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
 github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
+github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -44,6 +46,7 @@ github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
 github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
+github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
 github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
 github.com/zeebo/assert v0.0.0-20181109011804-10f827ce2ed6/go.mod h1:yssERNPivllc1yU3BvpjYI5BUW+zglcz6QWqeVRL5t0=
 github.com/zeebo/assert v1.1.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
@@ -51,7 +54,6 @@ github.com/zeebo/blake3 v0.0.4/go.mod h1:YOZo8A49yNqM0X/Y+JmDUZshJWLt1laHsNSn5ny
 github.com/zeebo/pcg v0.0.0-20181207190024-3cdc6b625a05/go.mod h1:Gr+78ptB0MwXxm//LBaEvBiaXY7hXJ6KGe2V32X2F6E=
 gitlab.com/elixxir/crypto v0.0.0-20200804182833-984246dea2c4/go.mod h1:ucm9SFKJo+K0N2GwRRpaNr+tKXMIOVWzmyUD0SbOu2c=
 gitlab.com/elixxir/crypto v0.0.3/go.mod h1:ZNgBOblhYToR4m8tj4cMvJ9UsJAUKq+p0gCp07WQmhA=
-gitlab.com/elixxir/crypto v0.0.6 h1:c94CGzBTV7LgInGHfmeJHrqq9nIc/WEOLUd9OeQBN74=
 gitlab.com/elixxir/primitives v0.0.0-20200731184040-494269b53b4d/go.mod h1:OQgUZq7SjnE0b+8+iIAT2eqQF+2IFHn73tOo+aV11mg=
 gitlab.com/elixxir/primitives v0.0.0-20200804170709-a1896d262cd9/go.mod h1:p0VelQda72OzoUckr1O+vPW0AiFe0nyKQ6gYcmFSuF8=
 gitlab.com/elixxir/primitives v0.0.0-20200804182913-788f47bded40/go.mod h1:tzdFFvb1ESmuTCOl1z6+yf6oAICDxH2NPUemVgoNLxc=
@@ -119,8 +121,10 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi
 google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
 gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
diff --git a/id/ephemeral/id.go b/id/ephemeral/id.go
index 598941d75e91fb82693de5fbc254da1d8942fed0..cdbeaa886bea841561de5937c7ba1e589a1fd146 100644
--- a/id/ephemeral/id.go
+++ b/id/ephemeral/id.go
@@ -1,11 +1,13 @@
 package ephemeral
 
 import (
+	"bytes"
 	"crypto"
 	"encoding/binary"
 	"fmt"
 	"github.com/pkg/errors"
 	"gitlab.com/xx_network/primitives/id"
+	"hash"
 	"io"
 	"math"
 	"time"
@@ -15,6 +17,14 @@ const Period = int64(time.Hour * 24)
 const NumOffsets int64 = 1 << 16
 const NsPerOffset = Period / NumOffsets
 
+// Ephemeral Ids reserved for specific actions:
+// All zero's denote a dummy ID
+// All one's denote a payment
+var ReservedIDs = []Id{
+	{0, 0, 0, 0, 0, 0, 0, 0},
+	{1, 1, 1, 1, 1, 1, 1, 1},
+}
+
 // Ephemeral ID type alias
 type Id [8]byte
 
@@ -144,19 +154,51 @@ func GetIdFromIntermediary(iid []byte, size uint, timestamp int64) (Id, time.Tim
 		return Id{}, time.Time{}, time.Time{}, errors.New("Cannot generate ID with size > 64")
 	}
 	salt, start, end := getRotationSalt(iid, timestamp)
+
+	// Continually generate an ephemeral Id until we land on
+	// an id not within the reserved list of Ids
+	eid := Id{}
+	var err error
+	for reserved := true; reserved; reserved = IsReserved(eid) {
+		eid, err = getIdFromIntermediaryHelper(b2b, iid, salt, size)
+		if err != nil {
+			return Id{}, start, end, err
+		}
+	}
+	return eid, start, end, nil
+}
+
+// Helper function which generates a single ephemeral Id
+func getIdFromIntermediaryHelper(b2b hash.Hash, iid, salt []byte, size uint) (Id, error) {
+	eid := Id{}
+
 	_, err := b2b.Write(iid)
 	if err != nil {
-		return Id{}, start, end, err
+		return Id{}, err
 	}
 	_, err = b2b.Write(salt)
 	if err != nil {
-		return Id{}, start, end, err
+		return Id{}, err
 	}
-	eid := Id{}
+
 	copy(eid[:], b2b.Sum(nil))
+
 	cleared := eid.Clear(size)
 	copy(eid[:], cleared[:])
-	return eid, start, end, nil
+
+	return eid, err
+}
+
+// Checks if the Id passed in is  among
+// the reserved global reserved ID list.
+// Returns true if reserved, false if non-reserved
+func IsReserved(eid Id) bool {
+	for _, r := range ReservedIDs {
+		if bytes.Equal(eid[:], r[:]) {
+			return true
+		}
+	}
+	return false
 }
 
 // getRotationSalt returns rotation salt based on ID hash and timestamp
diff --git a/id/ephemeral/id_test.go b/id/ephemeral/id_test.go
index fd452c3c71806a4274254fd48a5cabcaa3163f3b..b6b209dbcd1fef141782d96546b62a9fffb3b5f5 100644
--- a/id/ephemeral/id_test.go
+++ b/id/ephemeral/id_test.go
@@ -2,11 +2,13 @@ package ephemeral
 
 import (
 	"bytes"
+	"crypto"
 	"encoding/binary"
 	"gitlab.com/xx_network/crypto/csprng"
 	"gitlab.com/xx_network/primitives/id"
 	_ "golang.org/x/crypto/blake2b"
 	"math"
+	"strconv"
 	"testing"
 	"time"
 )
@@ -88,6 +90,87 @@ func TestGetIdFromIntermediary(t *testing.T) {
 	}
 }
 
+// Check that given precomputed input that should generate a reserved
+// ephemeral ID, GetIdFromIntermediary does not generate a reserved Id
+func TestGetIdFromIntermediary_Reserved(t *testing.T) {
+
+	// Hardcoded to ensure a collision with a reserved ID
+	hardcodedTimestamp := int64(1614199942358373731)
+	size := uint(4)
+	testId := id.NewIdFromString(strconv.Itoa(41), id.User, t)
+
+	// Intermediary ID expected to generate a reserved ephemeral ID
+	iid, err := GetIntermediaryId(testId)
+	if err != nil {
+		t.Errorf("Failed to get intermediary id: %+v", err)
+	}
+	// Generate an ephemeral Id given the input above. This specific
+	// call does not check if the outputted Id is reserved
+	salt, _, _ := getRotationSalt(iid, hardcodedTimestamp)
+	b2b := crypto.BLAKE2b_256.New()
+	expectedReservedEID, err := getIdFromIntermediaryHelper(b2b, iid, salt, size)
+	if err != nil {
+		t.Errorf("Failed to get id from intermediary: %+v", err)
+	}
+
+	// Check that the ephemeral Id generated with hardcoded data is a reserved ID
+	if !IsReserved(expectedReservedEID) {
+		t.Errorf("Expected reserved eid is no longer reserved, " +
+			"\n\tmay need to find a new ID. Use FindReservedID in this case.")
+	}
+
+	// Generate an ephemeral ID which given the same input above with the production facing call
+	eid, _, _, err := GetIdFromIntermediary(iid, size, hardcodedTimestamp)
+	if err != nil {
+		t.Errorf("Failed to get id from intermediary: %+v", err)
+	}
+
+	// Check that the ephemeralID generated is not reserved.
+	if IsReserved(eid) {
+		t.Errorf("Ephemeral ID generated should not be reserved!"+
+			"\n\tReserved IDs: %v"+
+			"\n\tGenerated ID: %v", ReservedIDs, eid)
+	}
+
+}
+
+// Will find a reserved ephemeral ID and returns the
+// associated intermediary ID
+func FindReservedID(size uint, timestamp int64, t *testing.T) []byte {
+	b2b := crypto.BLAKE2b_256.New()
+
+	// Loops through until a reserved ID is found
+	counter := 0
+	for {
+		testId := id.NewIdFromString(strconv.Itoa(counter), id.User, t)
+		iid, err := GetIntermediaryId(testId)
+		if err != nil {
+			t.Errorf("Failed to get intermediary id: %+v", err)
+		}
+
+		// Generate an ephemeral ID
+		salt, _, _ := getRotationSalt(iid, timestamp)
+		eid, err := getIdFromIntermediaryHelper(b2b, iid, salt, size)
+		if err != nil {
+			t.Errorf("Failed to get id from intermediary: %+v", err)
+		}
+
+		// Check if ephemeral ID is reserved exit
+		if IsReserved(eid) {
+			t.Logf("Found input which generates a reserved id. Input as follows."+
+				"\n\tSize: %d"+
+				"\n\tTimestamp: %d"+
+				"\n\tTestID: %v"+
+				"\n\tTestID generated using the following line of code: "+
+				"\n\t\ttestId := id.NewIdFromString(strconv.Itoa(%d), id.User, t)",
+				size, timestamp, testId, counter)
+			return iid
+		}
+		// Increment the counter
+		counter++
+	}
+}
+
 func TestId_Clear(t *testing.T) {
 	eid := Id{}
 	dummyData := []byte{201, 99, 103, 45, 68, 2, 56, 7}
diff --git a/ndf/ndf.go b/ndf/ndf.go
index a4751677a14eab639b1b9aaa0dc551458c6e0e67..7f3e5a4cd17f75eabdc53fdc0b5cf0336ae83f2a 100644
--- a/ndf/ndf.go
+++ b/ndf/ndf.go
@@ -4,34 +4,26 @@
 // Use of this source code is governed by a license that can be found in the LICENSE file //
 ////////////////////////////////////////////////////////////////////////////////////////////
 
-// Package ndf contains the structure for our network definition file. This object is used by
-// various users, including our cMix nodes and clients of the xx Messenger, among others.
-// It also includes functions to unmarshal an NDF from a JSON file, separate the signature
-// from the actual NDF content, and serialize the NDF structure into a byte slice
+// Package ndf contains the structure for the network definition file. It is
+// generated by permissioning and propagates to nodes, gateways, and clients in
+// the network.
 
 package ndf
 
 import (
-	"encoding/base64"
 	"encoding/json"
 	"github.com/pkg/errors"
 	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/xx_network/primitives/id"
-	"strings"
 	"time"
 )
 
-// This constant string is to be used by our users that request NDFs from permissioning.
-// Those that request include cMix nodes, gateways, notification bot and clients.
-// Permissioning builds and provides the ndf to those that request it. However, depending on
-// the status of the cMix network, it might not have the the ndf ready upon request.
-// Permissioning in this case tells the requester that it is not ready with an error message.
-// The requester checks if the error message contains this string, and thus knows it needs to ask
-// again.
+// NO_NDF is a string that the permissioning server responds with when a member
+// of the network requests an NDF from it but the NDF is not yet available.
 const NO_NDF = "Contacted server does not have an ndf to give"
 
-// NetworkDefinition structure matches the JSON structure generated in
-// Terraform, which allows it to be decoded to Go.
+// NetworkDefinition structure hold connection and network information. It
+// matches the JSON structure generated in Terraform.
 type NetworkDefinition struct {
 	Timestamp        time.Time
 	Gateways         []Gateway
@@ -42,35 +34,39 @@ type NetworkDefinition struct {
 	E2E              Group `json:"E2e"`
 	CMIX             Group `json:"Cmix"`
 	AddressSpaceSize uint32
+	ClientVersion    string
 }
 
-// Gateway is the structure for the gateways object in the JSON file.
+// Gateway contains the connection and identity information of a gateway on the
+// network.
 type Gateway struct {
 	ID             []byte `json:"Id"`
 	Address        string
 	TlsCertificate string `json:"Tls_certificate"`
 }
 
-// Node is the structure for the nodes object in the JSON file.
+// Node contains the connection and identity information of a node on the
+// network.
 type Node struct {
 	ID             []byte `json:"Id"`
 	Address        string
 	TlsCertificate string `json:"Tls_certificate"`
 }
 
-// Registration is the structure for the registration object in the JSON file.
+// Registration contains the connection information for the permissioning
+// server.
 type Registration struct {
 	Address        string
 	TlsCertificate string `json:"Tls_certificate"`
 }
 
-// Notifications is the structure for the registration object in the JSON file.
+// Notification contains the connection information for the notification bot.
 type Notification struct {
 	Address        string
 	TlsCertificate string `json:"Tls_certificate"`
 }
 
-// UDB is the structure for the UDB object in the JSON file.
+// UDB contains the ID and public key in PEM form for user discovery.
 type UDB struct {
 	ID       []byte `json:"Id"`
 	Cert     string `json:"Cert"`
@@ -78,8 +74,7 @@ type UDB struct {
 	DhPubKey []byte `json:"DhPubKey"`
 }
 
-// Group is the structure for a group in the JSON file; it is used for the E2E
-// and CMIX objects.
+// Group contains the information used to reconstruct a cyclic group.
 type Group struct {
 	Prime      string
 	SmallPrime string `json:"Small_prime"`
@@ -95,42 +90,29 @@ func (g *Group) String() (string, error) {
 	return string(data), nil
 }
 
-// DecodeNDF decodes the given JSON string into the NetworkDefinition structure
-// and decodes the base 64 signature to a byte slice. The NDF string is expected
-// to have the JSON data on line 1 and its signature on line 2. Returns an error
-// if separating the lines fails or if the JSON unmarshal fails.
-func DecodeNDF(ndf string) (*NetworkDefinition, []byte, error) {
-	// Get JSON data and check if the separating failed
-	jsonData, signature := separate(ndf)
-
-	// Decode the signature form base 64 and check for errors
-	signatureBytes, err := base64.StdEncoding.DecodeString(signature)
-	if err != nil {
-		return nil, nil, err
-	}
-
-	// Unmarshal the JSON string into a structure
-	networkDefinition := &NetworkDefinition{}
-	err = json.Unmarshal([]byte(jsonData), networkDefinition)
-	if err != nil {
-		return nil, nil, err
-	}
+// Marshal returns the JSON encoding of the NDF.
+func (ndf *NetworkDefinition) Marshal() ([]byte, error) {
+	return json.Marshal(ndf)
+}
 
-	return networkDefinition, signatureBytes, nil
+// Unmarshal parses the JSON encoded data and returns the resulting
+// NetworkDefinition.
+func Unmarshal(data []byte) (*NetworkDefinition, error) {
+	ndf := &NetworkDefinition{}
+	err := json.Unmarshal(data, ndf)
+	return ndf, err
 }
 
-// Returns a stripped down copy of the NDF object to be used by Clients
+// StripNdf returns a stripped down copy of the NetworkDefinition to be used by
+// Clients.
 func (ndf *NetworkDefinition) StripNdf() *NetworkDefinition {
-	// Strip down nodes slice of addresses and certs
+	// Remove address and TLS cert for every node.
 	var strippedNodes []Node
 	for _, node := range ndf.Nodes {
-		newNode := Node{
-			ID: node.ID,
-		}
-		strippedNodes = append(strippedNodes, newNode)
+		strippedNodes = append(strippedNodes, Node{ID: node.ID})
 	}
 
-	// Create a new Ndf with the stripped information
+	// Create a new NetworkDefinition with the stripped information
 	return &NetworkDefinition{
 		Timestamp:        ndf.Timestamp,
 		Gateways:         ndf.Gateways,
@@ -144,34 +126,9 @@ func (ndf *NetworkDefinition) StripNdf() *NetworkDefinition {
 	}
 }
 
-// separate splits the JSON data from the signature. The NDF string is expected
-// to have the JSON data starting on line 1 and its signature on the last line.
-// Returns JSON data and signature as separate strings. If the signature is not
-// present, it is returned as an empty string.
-func separate(ndf string) (string, string) {
-	var jsonLineEnd int
-	var signature string
-	lines := strings.Split(ndf, "\n")
-
-	// Determine which line the JSON ends and which line the signature is on
-	for i := len(lines) - 1; i >= 0; i-- {
-		line := strings.TrimSpace(lines[i])
-		if line != "" {
-			if strings.HasSuffix(line, "}") {
-				jsonLineEnd = i
-				break
-			} else {
-				signature = line
-			}
-		}
-	}
-
-	return strings.Join(lines[0:jsonLineEnd+1], "\n"), signature
-}
-
-// Serialize converts the NetworkDefinition into a byte slice.
+// Serialize serializes the NetworkDefinition into a byte slice.
 func (ndf *NetworkDefinition) Serialize() []byte {
-	b := make([]byte, 0)
+	var b []byte
 
 	// Convert timestamp to a byte slice
 	timeBytes, err := ndf.Timestamp.MarshalBinary()
@@ -218,34 +175,12 @@ func (ndf *NetworkDefinition) Serialize() []byte {
 	return b
 }
 
-// Marshal returns a json marshal of the ndf
-func (ndf *NetworkDefinition) Marshal() ([]byte, error) {
-	ndfBytes, err := json.Marshal(ndf)
-	if err != nil {
-		return nil, err
-	}
-
-	return ndfBytes, nil
-}
-
-// GetNodeId marshals the node id into the ID type. Returns an error if Marshal
-// fails.
+// GetNodeId unmarshalls the Node's ID bytes into an id.ID and returns it.
 func (n *Node) GetNodeId() (*id.ID, error) {
-	newID, err := id.Unmarshal(n.ID)
-	if err != nil {
-		return nil, err
-	}
-
-	return newID, nil
-
+	return id.Unmarshal(n.ID)
 }
 
-// GetGatewayId formats the gateway id into the id format specified in the id package of this repo
-func (n *Gateway) GetGatewayId() (*id.ID, error) {
-	newID, err := id.Unmarshal(n.ID)
-	if err != nil {
-		return nil, err
-	}
-
-	return newID, nil
+// GetGatewayId unmarshalls the Gateway's ID bytes into an id.ID and returns it.
+func (g *Gateway) GetGatewayId() (*id.ID, error) {
+	return id.Unmarshal(g.ID)
 }
diff --git a/ndf/ndf_test.go b/ndf/ndf_test.go
index e624a9355209e2c3a56e600f1f8765ceb66bd36f..1bf2a2348d961c407e1e17cc7462110c3351dd8f 100644
--- a/ndf/ndf_test.go
+++ b/ndf/ndf_test.go
@@ -10,9 +10,8 @@ import (
 	"bytes"
 	"encoding/base64"
 	"encoding/json"
-	"errors"
+	"fmt"
 	"reflect"
-	"strings"
 	"testing"
 	"time"
 )
@@ -76,37 +75,27 @@ var (
 		"Generator": "02"
 	}
 }`
-	ExampleSignature  = `gkh98J10rQiuVsEXd6xe8IeCINplnD93CFpXZFNjT1CgNMxgsHumiC5HsctjnF0xTxDPq3hn3/J0s+eblSVyGMMszTIoWNINVSS1fkm0EGkKafC1vKTZMmc9ivsWL7oY`
-	ExampleNDF        = ExampleJSON + "\n" + ExampleSignature
-	JsonBytes, _      = base64.StdEncoding.DecodeString("AQAAAA7UiTKgAAAAAP5cNTIuMjUuMTM1LjUyLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURnVENDQW1tZ0F3SUJBZ0lKQUtMZFo4VWlnSUFlTUEwR0NTcUdTSWIzRFFFQkJRVUFNRzh4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReApHekFaQmdOVkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVhTUJnR0ExVUVBd3dSWjJGMFpYZGhlU291ClkyMXBlQzV5YVhBd0hoY05NVGt3TXpBMU1UZ3pOVFUwV2hjTk1qa3dNekF5TVRnek5UVTBXakJ2TVFzd0NRWUQKVlFRR0V3SlZVekVUTUJFR0ExVUVDQXdLUTJGc2FXWnZjbTVwWVRFU01CQUdBMVVFQnd3SlEyeGhjbVZ0YjI1MApNUnN3R1FZRFZRUUtEQkpRY21sMllYUmxaM0pwZEhrZ1EyOXljQzR4R2pBWUJnTlZCQU1NRVdkaGRHVjNZWGtxCkxtTnRhWGd1Y21sd01JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBOStBYXh3RFAKeEhiaExtbjRIb1p1MG9VTTQ4UXVmYzZUNVhFWlRycE1ycUpBb3VYays2MUpjMEVGSDk2L3NiajdWeXZuWFBSbwpnSUVOYmsyWTg0QmtCOVNrUk1JWHlhL2doOWRPRURTZ252ai95ZzI0bDNiZEtGcUJNS2lGZzAwUFlCMzBmVStBCmJlM09JL2xlMEkrdisrUndIMkFWMEJNcStUNlBjQUdqQ0MxUTFaQjB3UDkvVnFOTVdxNWxiSzl3RDQ2SVFpU2kKK1NnSVFlRTdIb2lBWlhyR08wWTdsOVAzK1ZSb1hqUlFicWZuM0VUTkw5WnZRdWFyd0FZQzlJeDVNeFVyUzVhZwpPbWZqYzhiZmtwWURGQVhSWG1kS05JU0ptdENlYlgya0RycFA4QmRhc3g3RnpzeDU5Y0VVSENsMmFKT1dYYzdSCjVtM2p1T1ZMMUhVeGpRSURBUUFCb3lBd0hqQWNCZ05WSFJFRUZUQVRnaEZuWVhSbGQyRjVLaTVqYldsNExuSnAKY0RBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQU11M3hvYzJMVzJVRXhBQUlZWVdFRVRnZ0xOcmxHb254dGVTdQpqdUpqT1IraWs1U1ZMbjBsRXUyMit6K0ZDQTdnU2s5RmtXdSt2OXFuZk9mbTJBbStXS1lXdjNkSjVSeXBXL2hECk5Ya09ZeFZKTllGeGVTaG5Ib2hOcXE0ZURLcGRxU3hFY3VFckZYSmRMYlpQMXVOczRXSU9LblRoZ3poa3B1eTcKdFpSb3N2T0YxWDV1TDFmclZKekhONWpBU0VEQWE3aEpObVEyNGtoK2RzL0dlMzlmR0Q4cEszMUNXaG5JWGVEbwp2S0Q3d2l2aS9nU09CdGNSV1dMdlU4U2l6WmtTM2hnVHcwbFNPZjVnZXV6dmFzQ0VZbHFyS0Zzc2o2Y1R6YkNCCnh5M3JhM1dhelJUTlRXNFRta0hsQ1VDOUkzb1dUVHh3NWlReEYvSTJrUVFud1I3TDN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLTUyLjI1LjIxOS4zOC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEZ1RDQ0FtbWdBd0lCQWdJSkFLTGRaOFVpZ0lBZU1BMEdDU3FHU0liM0RRRUJCUVVBTUc4eEN6QUpCZ05WCkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5WlcxdmJuUXgKR3pBWkJnTlZCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFYU1CZ0dBMVVFQXd3UloyRjBaWGRoZVNvdQpZMjFwZUM1eWFYQXdIaGNOTVRrd016QTFNVGd6TlRVMFdoY05Namt3TXpBeU1UZ3pOVFUwV2pCdk1Rc3dDUVlEClZRUUdFd0pWVXpFVE1CRUdBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVNNQkFHQTFVRUJ3d0pRMnhoY21WdGIyNTAKTVJzd0dRWURWUVFLREJKUWNtbDJZWFJsWjNKcGRIa2dRMjl5Y0M0eEdqQVlCZ05WQkFNTUVXZGhkR1YzWVhrcQpMbU50YVhndWNtbHdNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTkrQWF4d0RQCnhIYmhMbW40SG9adTBvVU00OFF1ZmM2VDVYRVpUcnBNcnFKQW91WGsrNjFKYzBFRkg5Ni9zYmo3Vnl2blhQUm8KZ0lFTmJrMlk4NEJrQjlTa1JNSVh5YS9naDlkT0VEU2dudmoveWcyNGwzYmRLRnFCTUtpRmcwMFBZQjMwZlUrQQpiZTNPSS9sZTBJK3YrK1J3SDJBVjBCTXErVDZQY0FHakNDMVExWkIwd1A5L1ZxTk1XcTVsYks5d0Q0NklRaVNpCitTZ0lRZUU3SG9pQVpYckdPMFk3bDlQMytWUm9YalJRYnFmbjNFVE5MOVp2UXVhcndBWUM5SXg1TXhVclM1YWcKT21mamM4YmZrcFlERkFYUlhtZEtOSVNKbXRDZWJYMmtEcnBQOEJkYXN4N0Z6c3g1OWNFVUhDbDJhSk9XWGM3Ugo1bTNqdU9WTDFIVXhqUUlEQVFBQm95QXdIakFjQmdOVkhSRUVGVEFUZ2hGbllYUmxkMkY1S2k1amJXbDRMbkpwCmNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFNdTN4b2MyTFcyVUV4QUFJWVlXRUVUZ2dMTnJsR29ueHRlU3UKanVKak9SK2lrNVNWTG4wbEV1MjIreitGQ0E3Z1NrOUZrV3UrdjlxbmZPZm0yQW0rV0tZV3YzZEo1UnlwVy9oRApOWGtPWXhWSk5ZRnhlU2huSG9oTnFxNGVES3BkcVN4RWN1RXJGWEpkTGJaUDF1TnM0V0lPS25UaGd6aGtwdXk3CnRaUm9zdk9GMVg1dUwxZnJWSnpITjVqQVNFREFhN2hKTm1RMjRraCtkcy9HZTM5ZkdEOHBLMzFDV2huSVhlRG8KdktEN3dpdmkvZ1NPQnRjUldXTHZVOFNpelprUzNoZ1R3MGxTT2Y1Z2V1enZhc0NFWWxxcktGc3NqNmNUemJDQgp4eTNyYTNXYXpSVE5UVzRUbWtIbENVQzlJM29XVFR4dzVpUXhGL0kya1FRbndSN0wzdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS01Mi40MS44MC4xMDQtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGdUQ0NBbW1nQXdJQkFnSUpBS0xkWjhVaWdJQWVNQTBHQ1NxR1NJYjNEUUVCQlFVQU1HOHhDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSURBcERZV3hwWm05eWJtbGhNUkl3RUFZRFZRUUhEQWxEYkdGeVpXMXZiblF4Ckd6QVpCZ05WQkFvTUVsQnlhWFpoZEdWbmNtbDBlU0JEYjNKd0xqRWFNQmdHQTFVRUF3d1JaMkYwWlhkaGVTb3UKWTIxcGVDNXlhWEF3SGhjTk1Ua3dNekExTVRnek5UVTBXaGNOTWprd016QXlNVGd6TlRVMFdqQnZNUXN3Q1FZRApWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVTTUJBR0ExVUVCd3dKUTJ4aGNtVnRiMjUwCk1Sc3dHUVlEVlFRS0RCSlFjbWwyWVhSbFozSnBkSGtnUTI5eWNDNHhHakFZQmdOVkJBTU1FV2RoZEdWM1lYa3EKTG1OdGFYZ3VjbWx3TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE5K0FheHdEUAp4SGJoTG1uNEhvWnUwb1VNNDhRdWZjNlQ1WEVaVHJwTXJxSkFvdVhrKzYxSmMwRUZIOTYvc2JqN1Z5dm5YUFJvCmdJRU5iazJZODRCa0I5U2tSTUlYeWEvZ2g5ZE9FRFNnbnZqL3lnMjRsM2JkS0ZxQk1LaUZnMDBQWUIzMGZVK0EKYmUzT0kvbGUwSSt2KytSd0gyQVYwQk1xK1Q2UGNBR2pDQzFRMVpCMHdQOS9WcU5NV3E1bGJLOXdENDZJUWlTaQorU2dJUWVFN0hvaUFaWHJHTzBZN2w5UDMrVlJvWGpSUWJxZm4zRVROTDladlF1YXJ3QVlDOUl4NU14VXJTNWFnCk9tZmpjOGJma3BZREZBWFJYbWRLTklTSm10Q2ViWDJrRHJwUDhCZGFzeDdGenN4NTljRVVIQ2wyYUpPV1hjN1IKNW0zanVPVkwxSFV4alFJREFRQUJveUF3SGpBY0JnTlZIUkVFRlRBVGdoRm5ZWFJsZDJGNUtpNWpiV2w0TG5KcApjREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBTXUzeG9jMkxXMlVFeEFBSVlZV0VFVGdnTE5ybEdvbnh0ZVN1Cmp1SmpPUitpazVTVkxuMGxFdTIyK3orRkNBN2dTazlGa1d1K3Y5cW5mT2ZtMkFtK1dLWVd2M2RKNVJ5cFcvaEQKTlhrT1l4VkpOWUZ4ZVNobkhvaE5xcTRlREtwZHFTeEVjdUVyRlhKZExiWlAxdU5zNFdJT0tuVGhnemhrcHV5Nwp0WlJvc3ZPRjFYNXVMMWZyVkp6SE41akFTRURBYTdoSk5tUTI0a2grZHMvR2UzOWZHRDhwSzMxQ1dobklYZURvCnZLRDd3aXZpL2dTT0J0Y1JXV0x2VThTaXpaa1MzaGdUdzBsU09mNWdldXp2YXNDRVlscXJLRnNzajZjVHpiQ0IKeHkzcmEzV2F6UlROVFc0VG1rSGxDVUM5STNvV1RUeHc1aVF4Ri9JMmtRUW53UjdMM3c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTguMjM3LjE0Ny4xMDUtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGJEQ0NBbFNnQXdJQkFnSUpBT1VOdFpuZUlZRUNNQTBHQ1NxR1NJYjNEUUVCQlFVQU1HZ3hDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSURBcERZV3hwWm05eWJtbGhNUkl3RUFZRFZRUUhEQWxEYkdGeVpXMXZiblF4Ckd6QVpCZ05WQkFvTUVsQnlhWFpoZEdWbmNtbDBlU0JEYjNKd0xqRVRNQkVHQTFVRUF3d0tLaTVqYldsNExuSnAKY0RBZUZ3MHhPVEF6TURVeE9ETTFORE5hRncweU9UQXpNREl4T0RNMU5ETmFNR2d4Q3pBSkJnTlZCQVlUQWxWVApNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReEd6QVpCZ05WCkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVUTUJFR0ExVUVBd3dLS2k1amJXbDRMbkpwY0RDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQVBQMFd5VmtmWkEvQ0VkMkRnS3BjdWRuMG9EaApEd3NqbXg4TEJEV3NVZ1F6eUxyRmlWaWdmVW1VZWZrblVIM2RUSmptaUp0R3FMc2F5Q25XZHFXTEhQSll2RmZzCldZVzBJR0Y5M1VHLzRONVVBV080b2tDM0NZZ0tTaTRla3BmdzJ6Z1pxMGdtYnpUblhjSEY5Z2ZtUTdqSlVLU0UKdEpQU056WHErUFplSlRDOXpKQWI0TGo4UXpIMThyRE04RGFMMnkxbnMwWTJIdTBlZEJGbi9PcWF2QkpLYi91QQptM0FFanFlT2hDN0VRVWpWYW1XbFRCUHQ0MCtCLzZhRkpYNUJZbTJKRmtSc0dCSXlCVkw0Nk12QzAyTWd6VFQ5CmJKSUpmd3FtQmFUcnV3ZW1OZ3pHdTdKazAzaHFxUzFUVUV2U0k2L3g4YlZvYmEzb3JjS2tmOUhzRGpFQ0F3RUEKQWFNWk1CY3dGUVlEVlIwUkJBNHdESUlLS2k1amJXbDRMbkpwY0RBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQQpuZVVvY040QWJjUUFDMStiM1RvOHU1VUdkYUd4aGNHeVpCbEFvZW5SVmRqWEszbFRqc01kTVdiNFFjdGdOZklmClUvenVVbjJteFRtRi9la1AwZ0NDZ3RsZVpyOStEWUtVNWhsWGs4SzEwdUt4R0Q2RXZvaVhaemxmZVV1b3RncDIKcXZJM3lzT20vaHZDZnlFa3FoZkh0YnhqVjdqN3Y3ZVFGUGJ2TmFYYkxhMHlyNEM0dk1LL1owOVVpOUpyWi9aNApjeUlreGZDNi9yT3FBaXJTZElwMDlFR2l3N0dNOGd1SHlnZ0U0SWlackRzbFQ4VjN4SWw5ODVjYkN4U3hlVzFSCnRnSDRyZEVYdVZlOSszMW9KaG1YT0U5dXgyakNvcDl0RUpNZ1dnN0hTdHJKNXBsUGJiK0htam9YM25CTzA0RTUKNm01MlB5ek1OVisyTjIxSVBwcEt3QT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1Mi4xMS4xMzYuMjM4LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURiRENDQWxTZ0F3SUJBZ0lKQU9VTnRabmVJWUVDTUEwR0NTcUdTSWIzRFFFQkJRVUFNR2d4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReApHekFaQmdOVkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVUTUJFR0ExVUVBd3dLS2k1amJXbDRMbkpwCmNEQWVGdzB4T1RBek1EVXhPRE0xTkROYUZ3MHlPVEF6TURJeE9ETTFORE5hTUdneEN6QUpCZ05WQkFZVEFsVlQKTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5WlcxdmJuUXhHekFaQmdOVgpCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFVE1CRUdBMVVFQXd3S0tpNWpiV2w0TG5KcGNEQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFQUDBXeVZrZlpBL0NFZDJEZ0twY3VkbjBvRGgKRHdzam14OExCRFdzVWdRenlMckZpVmlnZlVtVWVma25VSDNkVEpqbWlKdEdxTHNheUNuV2RxV0xIUEpZdkZmcwpXWVcwSUdGOTNVRy80TjVVQVdPNG9rQzNDWWdLU2k0ZWtwZncyemdacTBnbWJ6VG5YY0hGOWdmbVE3akpVS1NFCnRKUFNOelhxK1BaZUpUQzl6SkFiNExqOFF6SDE4ckRNOERhTDJ5MW5zMFkySHUwZWRCRm4vT3FhdkJKS2IvdUEKbTNBRWpxZU9oQzdFUVVqVmFtV2xUQlB0NDArQi82YUZKWDVCWW0ySkZrUnNHQkl5QlZMNDZNdkMwMk1nelRUOQpiSklKZndxbUJhVHJ1d2VtTmd6R3U3SmswM2hxcVMxVFVFdlNJNi94OGJWb2JhM29yY0trZjlIc0RqRUNBd0VBCkFhTVpNQmN3RlFZRFZSMFJCQTR3RElJS0tpNWpiV2w0TG5KcGNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUEKbmVVb2NONEFiY1FBQzErYjNUbzh1NVVHZGFHeGhjR3laQmxBb2VuUlZkalhLM2xUanNNZE1XYjRRY3RnTmZJZgpVL3p1VW4ybXhUbUYvZWtQMGdDQ2d0bGVacjkrRFlLVTVobFhrOEsxMHVLeEdENkV2b2lYWnpsZmVVdW90Z3AyCnF2STN5c09tL2h2Q2Z5RWtxaGZIdGJ4alY3ajd2N2VRRlBidk5hWGJMYTB5cjRDNHZNSy9aMDlVaTlKclovWjQKY3lJa3hmQzYvck9xQWlyU2RJcDA5RUdpdzdHTThndUh5Z2dFNElpWnJEc2xUOFYzeElsOTg1Y2JDeFN4ZVcxUgp0Z0g0cmRFWHVWZTkrMzFvSmhtWE9FOXV4MmpDb3A5dEVKTWdXZzdIU3RySjVwbFBiYitIbWpvWDNuQk8wNEU1CjZtNTJQeXpNTlYrMk4yMUlQcHBLd0E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzQuMjEzLjc5LjMxLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURiRENDQWxTZ0F3SUJBZ0lKQU9VTnRabmVJWUVDTUEwR0NTcUdTSWIzRFFFQkJRVUFNR2d4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReApHekFaQmdOVkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVUTUJFR0ExVUVBd3dLS2k1amJXbDRMbkpwCmNEQWVGdzB4T1RBek1EVXhPRE0xTkROYUZ3MHlPVEF6TURJeE9ETTFORE5hTUdneEN6QUpCZ05WQkFZVEFsVlQKTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5WlcxdmJuUXhHekFaQmdOVgpCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFVE1CRUdBMVVFQXd3S0tpNWpiV2w0TG5KcGNEQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFQUDBXeVZrZlpBL0NFZDJEZ0twY3VkbjBvRGgKRHdzam14OExCRFdzVWdRenlMckZpVmlnZlVtVWVma25VSDNkVEpqbWlKdEdxTHNheUNuV2RxV0xIUEpZdkZmcwpXWVcwSUdGOTNVRy80TjVVQVdPNG9rQzNDWWdLU2k0ZWtwZncyemdacTBnbWJ6VG5YY0hGOWdmbVE3akpVS1NFCnRKUFNOelhxK1BaZUpUQzl6SkFiNExqOFF6SDE4ckRNOERhTDJ5MW5zMFkySHUwZWRCRm4vT3FhdkJKS2IvdUEKbTNBRWpxZU9oQzdFUVVqVmFtV2xUQlB0NDArQi82YUZKWDVCWW0ySkZrUnNHQkl5QlZMNDZNdkMwMk1nelRUOQpiSklKZndxbUJhVHJ1d2VtTmd6R3U3SmswM2hxcVMxVFVFdlNJNi94OGJWb2JhM29yY0trZjlIc0RqRUNBd0VBCkFhTVpNQmN3RlFZRFZSMFJCQTR3RElJS0tpNWpiV2w0TG5KcGNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUEKbmVVb2NONEFiY1FBQzErYjNUbzh1NVVHZGFHeGhjR3laQmxBb2VuUlZkalhLM2xUanNNZE1XYjRRY3RnTmZJZgpVL3p1VW4ybXhUbUYvZWtQMGdDQ2d0bGVacjkrRFlLVTVobFhrOEsxMHVLeEdENkV2b2lYWnpsZmVVdW90Z3AyCnF2STN5c09tL2h2Q2Z5RWtxaGZIdGJ4alY3ajd2N2VRRlBidk5hWGJMYTB5cjRDNHZNSy9aMDlVaTlKclovWjQKY3lJa3hmQzYvck9xQWlyU2RJcDA5RUdpdzdHTThndUh5Z2dFNElpWnJEc2xUOFYzeElsOTg1Y2JDeFN4ZVcxUgp0Z0g0cmRFWHVWZTkrMzFvSmhtWE9FOXV4MmpDb3A5dEVKTWdXZzdIU3RySjVwbFBiYitIbWpvWDNuQk8wNEU1CjZtNTJQeXpNTlYrMk4yMUlQcHBLd0E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tcmVnaXN0cmF0aW9uLmRlZmF1bHQuY21peC5yaXAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGtEQ0NBbmlnQXdJQkFnSUpBSm5qb3N1U3NQN2dNQTBHQ1NxR1NJYjNEUUVCQlFVQU1IUXhDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSURBcERZV3hwWm05eWJtbGhNUkl3RUFZRFZRUUhEQWxEYkdGeVpXMXZiblF4Ckd6QVpCZ05WQkFvTUVsQnlhWFpoZEdWbmNtbDBlU0JEYjNKd0xqRWZNQjBHQTFVRUF3d1djbVZuYVhOMGNtRjAKYVc5dUtpNWpiV2w0TG5KcGNEQWVGdzB4T1RBek1EVXlNVFE1TlRaYUZ3MHlPVEF6TURJeU1UUTVOVFphTUhReApDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5ClpXMXZiblF4R3pBWkJnTlZCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFZk1CMEdBMVVFQXd3V2NtVm4KYVhOMGNtRjBhVzl1S2k1amJXbDRMbkpwY0RDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQU9RS3ZxamRoMzVvK01FQ0JoQ3dvcEp6UGxRTm1xMmlQYmV3Uk50STAyYlVOSzNrTFFVYkZsWWR6TkdaClM0R1lYR2M1TytqZGk4U2x4ODJyMWtkano1UFBDTkZCQVJJc09QL0w4cjNER2VXK3llSmRnQlpqbTFzM3lsa2EKbXQ0QWppcS9iTmp5c1M2TC9XU09wK3NWdW1EeHRCRXpPL1VUVTFPNlFSbnpVcGhMYWlXRU5tRXJHdnNIMENaVgpxMzhJYTU4ay9RakNBenBVY1lpNGoybDFmYjA3eHFGY1FEOEg2U21VTTI5N1V5UW9zRHJwOHVrZElvMzFLb3hyCjRYRG5uTk5zWVN0QzI2dHpITWVLdUoyV2wrM1l6c1N5ZmxmTTJZRWNLRTMxc3FCOURTMzZVa0o4Sjg0ZUxzSE4KSW1HZzNXb2RGQXZpREI2NytqWERiQjMwTmtNQ0F3RUFBYU1sTUNNd0lRWURWUjBSQkJvd0dJSVdjbVZuYVhOMApjbUYwYVc5dUtpNWpiV2w0TG5KcGNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFGOW1OemsrZytvNjI2UmxsCnQzZjMvMXFJeVlRcllKMEJqU1dDS1lFRk1DZ1o0SmliQUpqQXZJYWpoVllFUnRsdGZmTStZS2NkRTJrVHBkekoKMFlKdVVuUmZ1djZzVm5YbFZWdWdVVW5kNElPaWdtamJDZE0zMmsxNzBDWU1tMGFpd0d4bDRGck5hOGVpN0FJYQp4L3MxbitzcVdxM0hlVzVMWGpub1ZiK3MzSGVDV0l1TGZjZ3J1cmZ5ZThGbk5oeTE0SEZ6eFZZWWVmSUttMFhMCitEUGxjR0dHbS9QUFl0M3U0YTIrclAzeGFpaGM2NWRUYTB1NXRmL1hQWHRQeFREUEZqMkplUURGeG83UVJSRWIKUEQ4OUN0WW53dVA5MzdDcmt2Q0tyTDBHa1cxRlZpWEtxWlk5RjV1aHhydkxJcHpoYk5ycy9FYnR3ZVkzNVhHTApEQ0NNa2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwdWJrZXkxLjIuMy40OjEyMzQBAgNGRkZGRkZGRkZGRkZGRkZGQzkwRkRBQTIyMTY4QzIzNEM0QzY2MjhCODBEQzFDRDEyOTAyNEUwODhBNjdDQzc0MDIwQkJFQTYzQjEzOUIyMjUxNEEwODc5OEUzNDA0RERFRjk1MTlCM0NEM0E0MzFCMzAyQjBBNkRGMjVGMTQzNzRGRTEzNTZENkQ1MUMyNDVFNDg1QjU3NjYyNUU3RUM2RjQ0QzQyRTlBNjM3RUQ2QjBCRkY1Q0I2RjQwNkI3RURFRTM4NkJGQjVBODk5RkE1QUU5RjI0MTE3QzRCMUZFNjQ5Mjg2NjUxRUNFNDVCM0RDMjAwN0NCOEExNjNCRjA1OThEQTQ4MzYxQzU1RDM5QTY5MTYzRkE4RkQyNENGNUY4MzY1NUQyM0RDQTNBRDk2MUM2MkYzNTYyMDg1NTJCQjlFRDUyOTA3NzA5Njk2NkQ2NzBDMzU0RTRBQkM5ODA0RjE3NDZDMDhDQTE4MjE3QzMyOTA1RTQ2MkUzNkNFM0JFMzlFNzcyQzE4MEU4NjAzOUIyNzgzQTJFQzA3QTI4RkI1QzU1REYwNkY0QzUyQzlERTJCQ0JGNjk1NTgxNzE4Mzk5NTQ5N0NFQTk1NkFFNTE1RDIyNjE4OThGQTA1MTAxNTcyOEU1QThBQUNBQTY4RkZGRkZGRkZGRkZGRkZGRjAyN0ZGRkZGRkZGRkZGRkZGRkU0ODdFRDUxMTBCNDYxMUE2MjYzMzE0NUMwNkUwRTY4OTQ4MTI3MDQ0NTMzRTYzQTAxMDVERjUzMUQ4OUNEOTEyOEE1MDQzQ0M3MUEwMjZFRjdDQThDRDlFNjlEMjE4RDk4MTU4NTM2RjkyRjhBMUJBN0YwOUFCNkI2QThFMTIyRjI0MkRBQkIzMTJGM0Y2MzdBMjYyMTc0RDMxQkY2QjU4NUZGQUU1QjdBMDM1QkY2RjcxQzM1RkRBRDQ0Q0ZEMkQ3NEY5MjA4QkUyNThGRjMyNDk0MzMyOEY2NzIyRDlFRTEwMDNFNUM1MEIxREY4MkNDNkQyNDFCMEUyQUU5Q0QzNDhCMUZENDdFOTI2N0FGQzFCMkFFOTFFRTUxRDZDQjBFMzE3OUFCMTA0MkE5NURDRjZBOTQ4M0I4NEI0QjM2QjM4NjFBQTcyNTVFNEMwMjc4QkEzNjA0NjUwQzEwQkUxOTQ4MkYyMzE3MUI2NzFERjFDRjNCOTYwQzA3NDMwMUNEOTNDMUQxNzYwM0QxNDdEQUUyQUVGODM3QTYyOTY0RUYxNUU1RkI0QUFDMEI4QzFDQ0FBNEJFNzU0QUI1NzI4QUU5MTMwQzRDN0QwMjg4MEFCOTQ3MkQ0NTU2NTUzNDdGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQzkwRkRBQTIyMTY4QzIzNEM0QzY2MjhCODBEQzFDRDEyOTAyNEUwODhBNjdDQzc0MDIwQkJFQTYzQjEzOUIyMjUxNEEwODc5OEUzNDA0RERFRjk1MTlCM0NEM0E0MzFCMzAyQjBBNkRGMjVGMTQzNzRGRTEzNTZENkQ1MUMyNDVFNDg1QjU3NjYyNUU3RUM2RjQ0QzQyRTlBNjM3RUQ2QjBCRkY1Q0I2RjQwNkI3RURFRTM4NkJGQjVBODk5RkE1QUU5RjI0MTE3QzRCMUZFNjQ5Mjg2NjUxRUNFNDVCM0RDMjAwN0NCOEExNjNCRjA1OThEQTQ4MzYxQzU1RDM5QTY5MTYzRkE4RkQyNENGNUY4MzY1NUQyM0RDQTNBRDk2MUM2MkYzNTYyMDg1NTJCQjlFRDUyOTA3NzA5Njk2NkQ2NzBDMzU0RTRBQkM5ODA0RjE3NDZDMDhDQTE4MjE3QzMyOTA1RTQ2MkUzNkNFM0JFMzlFNzcyQzE4MEU4NjAzOUIyNzgzQTJFQzA3QTI4RkI1QzU1REYwNkY0QzUyQzlERTJCQ0JGNjk1NTgxNzE4Mzk5NTQ5N0NFQTk1NkFFNTE1RDIyNjE4OThGQTA1MTAxNTcyOEU1QThBQUNBQTY4RkZGRkZGRkZGRkZGRkZGRjAyN0ZGRkZGRkZGRkZGRkZGRkU0ODdFRDUxMTBCNDYxMUE2MjYzMzE0NUMwNkUwRTY4OTQ4MTI3MDQ0NTMzRTYzQTAxMDVERjUzMUQ4OUNEOTEyOEE1MDQzQ0M3MUEwMjZFRjdDQThDRDlFNjlEMjE4RDk4MTU4NTM2RjkyRjhBMUJBN0YwOUFCNkI2QThFMTIyRjI0MkRBQkIzMTJGM0Y2MzdBMjYyMTc0RDMxQkY2QjU4NUZGQUU1QjdBMDM1QkY2RjcxQzM1RkRBRDQ0Q0ZEMkQ3NEY5MjA4QkUyNThGRjMyNDk0MzMyOEY2NzIyRDlFRTEwMDNFNUM1MEIxREY4MkNDNkQyNDFCMEUyQUU5Q0QzNDhCMUZENDdFOTI2N0FGQzFCMkFFOTFFRTUxRDZDQjBFMzE3OUFCMTA0MkE5NURDRjZBOTQ4M0I4NEI0QjM2QjM4NjFBQTcyNTVFNEMwMjc4QkEzNjA0NjUwQzEwQkUxOTQ4MkYyMzE3MUI2NzFERjFDRjNCOTYwQzA3NDMwMUNEOTNDMUQxNzYwM0QxNDdEQUUyQUVGODM3QTYyOTY0RUYxNUU1RkI0QUFDMEI4QzFDQ0FBNEJFNzU0QUI1NzI4QUU5MTMwQzRDN0QwMjg4MEFCOTQ3MkQ0NTU2NTUzNDdGRkZGRkZGRkZGRkZGRkY=")
-	SignatureBytes, _ = base64.StdEncoding.DecodeString(ExampleSignature)
+	ExampleNDF   = ExampleJSON
+	JsonBytes, _ = base64.StdEncoding.DecodeString("AQAAAA7UiTKgAAAAAP5cNTIuMjUuMTM1LjUyLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURnVENDQW1tZ0F3SUJBZ0lKQUtMZFo4VWlnSUFlTUEwR0NTcUdTSWIzRFFFQkJRVUFNRzh4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReApHekFaQmdOVkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVhTUJnR0ExVUVBd3dSWjJGMFpYZGhlU291ClkyMXBlQzV5YVhBd0hoY05NVGt3TXpBMU1UZ3pOVFUwV2hjTk1qa3dNekF5TVRnek5UVTBXakJ2TVFzd0NRWUQKVlFRR0V3SlZVekVUTUJFR0ExVUVDQXdLUTJGc2FXWnZjbTVwWVRFU01CQUdBMVVFQnd3SlEyeGhjbVZ0YjI1MApNUnN3R1FZRFZRUUtEQkpRY21sMllYUmxaM0pwZEhrZ1EyOXljQzR4R2pBWUJnTlZCQU1NRVdkaGRHVjNZWGtxCkxtTnRhWGd1Y21sd01JSUJJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBUThBTUlJQkNnS0NBUUVBOStBYXh3RFAKeEhiaExtbjRIb1p1MG9VTTQ4UXVmYzZUNVhFWlRycE1ycUpBb3VYays2MUpjMEVGSDk2L3NiajdWeXZuWFBSbwpnSUVOYmsyWTg0QmtCOVNrUk1JWHlhL2doOWRPRURTZ252ai95ZzI0bDNiZEtGcUJNS2lGZzAwUFlCMzBmVStBCmJlM09JL2xlMEkrdisrUndIMkFWMEJNcStUNlBjQUdqQ0MxUTFaQjB3UDkvVnFOTVdxNWxiSzl3RDQ2SVFpU2kKK1NnSVFlRTdIb2lBWlhyR08wWTdsOVAzK1ZSb1hqUlFicWZuM0VUTkw5WnZRdWFyd0FZQzlJeDVNeFVyUzVhZwpPbWZqYzhiZmtwWURGQVhSWG1kS05JU0ptdENlYlgya0RycFA4QmRhc3g3RnpzeDU5Y0VVSENsMmFKT1dYYzdSCjVtM2p1T1ZMMUhVeGpRSURBUUFCb3lBd0hqQWNCZ05WSFJFRUZUQVRnaEZuWVhSbGQyRjVLaTVqYldsNExuSnAKY0RBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQU11M3hvYzJMVzJVRXhBQUlZWVdFRVRnZ0xOcmxHb254dGVTdQpqdUpqT1IraWs1U1ZMbjBsRXUyMit6K0ZDQTdnU2s5RmtXdSt2OXFuZk9mbTJBbStXS1lXdjNkSjVSeXBXL2hECk5Ya09ZeFZKTllGeGVTaG5Ib2hOcXE0ZURLcGRxU3hFY3VFckZYSmRMYlpQMXVOczRXSU9LblRoZ3poa3B1eTcKdFpSb3N2T0YxWDV1TDFmclZKekhONWpBU0VEQWE3aEpObVEyNGtoK2RzL0dlMzlmR0Q4cEszMUNXaG5JWGVEbwp2S0Q3d2l2aS9nU09CdGNSV1dMdlU4U2l6WmtTM2hnVHcwbFNPZjVnZXV6dmFzQ0VZbHFyS0Zzc2o2Y1R6YkNCCnh5M3JhM1dhelJUTlRXNFRta0hsQ1VDOUkzb1dUVHh3NWlReEYvSTJrUVFud1I3TDN3PT0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLTUyLjI1LjIxOS4zOC0tLS0tQkVHSU4gQ0VSVElGSUNBVEUtLS0tLQpNSUlEZ1RDQ0FtbWdBd0lCQWdJSkFLTGRaOFVpZ0lBZU1BMEdDU3FHU0liM0RRRUJCUVVBTUc4eEN6QUpCZ05WCkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5WlcxdmJuUXgKR3pBWkJnTlZCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFYU1CZ0dBMVVFQXd3UloyRjBaWGRoZVNvdQpZMjFwZUM1eWFYQXdIaGNOTVRrd016QTFNVGd6TlRVMFdoY05Namt3TXpBeU1UZ3pOVFUwV2pCdk1Rc3dDUVlEClZRUUdFd0pWVXpFVE1CRUdBMVVFQ0F3S1EyRnNhV1p2Y201cFlURVNNQkFHQTFVRUJ3d0pRMnhoY21WdGIyNTAKTVJzd0dRWURWUVFLREJKUWNtbDJZWFJsWjNKcGRIa2dRMjl5Y0M0eEdqQVlCZ05WQkFNTUVXZGhkR1YzWVhrcQpMbU50YVhndWNtbHdNSUlCSWpBTkJna3Foa2lHOXcwQkFRRUZBQU9DQVE4QU1JSUJDZ0tDQVFFQTkrQWF4d0RQCnhIYmhMbW40SG9adTBvVU00OFF1ZmM2VDVYRVpUcnBNcnFKQW91WGsrNjFKYzBFRkg5Ni9zYmo3Vnl2blhQUm8KZ0lFTmJrMlk4NEJrQjlTa1JNSVh5YS9naDlkT0VEU2dudmoveWcyNGwzYmRLRnFCTUtpRmcwMFBZQjMwZlUrQQpiZTNPSS9sZTBJK3YrK1J3SDJBVjBCTXErVDZQY0FHakNDMVExWkIwd1A5L1ZxTk1XcTVsYks5d0Q0NklRaVNpCitTZ0lRZUU3SG9pQVpYckdPMFk3bDlQMytWUm9YalJRYnFmbjNFVE5MOVp2UXVhcndBWUM5SXg1TXhVclM1YWcKT21mamM4YmZrcFlERkFYUlhtZEtOSVNKbXRDZWJYMmtEcnBQOEJkYXN4N0Z6c3g1OWNFVUhDbDJhSk9XWGM3Ugo1bTNqdU9WTDFIVXhqUUlEQVFBQm95QXdIakFjQmdOVkhSRUVGVEFUZ2hGbllYUmxkMkY1S2k1amJXbDRMbkpwCmNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFNdTN4b2MyTFcyVUV4QUFJWVlXRUVUZ2dMTnJsR29ueHRlU3UKanVKak9SK2lrNVNWTG4wbEV1MjIreitGQ0E3Z1NrOUZrV3UrdjlxbmZPZm0yQW0rV0tZV3YzZEo1UnlwVy9oRApOWGtPWXhWSk5ZRnhlU2huSG9oTnFxNGVES3BkcVN4RWN1RXJGWEpkTGJaUDF1TnM0V0lPS25UaGd6aGtwdXk3CnRaUm9zdk9GMVg1dUwxZnJWSnpITjVqQVNFREFhN2hKTm1RMjRraCtkcy9HZTM5ZkdEOHBLMzFDV2huSVhlRG8KdktEN3dpdmkvZ1NPQnRjUldXTHZVOFNpelprUzNoZ1R3MGxTT2Y1Z2V1enZhc0NFWWxxcktGc3NqNmNUemJDQgp4eTNyYTNXYXpSVE5UVzRUbWtIbENVQzlJM29XVFR4dzVpUXhGL0kya1FRbndSN0wzdz09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS01Mi40MS44MC4xMDQtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGdUQ0NBbW1nQXdJQkFnSUpBS0xkWjhVaWdJQWVNQTBHQ1NxR1NJYjNEUUVCQlFVQU1HOHhDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSURBcERZV3hwWm05eWJtbGhNUkl3RUFZRFZRUUhEQWxEYkdGeVpXMXZiblF4Ckd6QVpCZ05WQkFvTUVsQnlhWFpoZEdWbmNtbDBlU0JEYjNKd0xqRWFNQmdHQTFVRUF3d1JaMkYwWlhkaGVTb3UKWTIxcGVDNXlhWEF3SGhjTk1Ua3dNekExTVRnek5UVTBXaGNOTWprd016QXlNVGd6TlRVMFdqQnZNUXN3Q1FZRApWUVFHRXdKVlV6RVRNQkVHQTFVRUNBd0tRMkZzYVdadmNtNXBZVEVTTUJBR0ExVUVCd3dKUTJ4aGNtVnRiMjUwCk1Sc3dHUVlEVlFRS0RCSlFjbWwyWVhSbFozSnBkSGtnUTI5eWNDNHhHakFZQmdOVkJBTU1FV2RoZEdWM1lYa3EKTG1OdGFYZ3VjbWx3TUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FROEFNSUlCQ2dLQ0FRRUE5K0FheHdEUAp4SGJoTG1uNEhvWnUwb1VNNDhRdWZjNlQ1WEVaVHJwTXJxSkFvdVhrKzYxSmMwRUZIOTYvc2JqN1Z5dm5YUFJvCmdJRU5iazJZODRCa0I5U2tSTUlYeWEvZ2g5ZE9FRFNnbnZqL3lnMjRsM2JkS0ZxQk1LaUZnMDBQWUIzMGZVK0EKYmUzT0kvbGUwSSt2KytSd0gyQVYwQk1xK1Q2UGNBR2pDQzFRMVpCMHdQOS9WcU5NV3E1bGJLOXdENDZJUWlTaQorU2dJUWVFN0hvaUFaWHJHTzBZN2w5UDMrVlJvWGpSUWJxZm4zRVROTDladlF1YXJ3QVlDOUl4NU14VXJTNWFnCk9tZmpjOGJma3BZREZBWFJYbWRLTklTSm10Q2ViWDJrRHJwUDhCZGFzeDdGenN4NTljRVVIQ2wyYUpPV1hjN1IKNW0zanVPVkwxSFV4alFJREFRQUJveUF3SGpBY0JnTlZIUkVFRlRBVGdoRm5ZWFJsZDJGNUtpNWpiV2w0TG5KcApjREFOQmdrcWhraUc5dzBCQVFVRkFBT0NBUUVBTXUzeG9jMkxXMlVFeEFBSVlZV0VFVGdnTE5ybEdvbnh0ZVN1Cmp1SmpPUitpazVTVkxuMGxFdTIyK3orRkNBN2dTazlGa1d1K3Y5cW5mT2ZtMkFtK1dLWVd2M2RKNVJ5cFcvaEQKTlhrT1l4VkpOWUZ4ZVNobkhvaE5xcTRlREtwZHFTeEVjdUVyRlhKZExiWlAxdU5zNFdJT0tuVGhnemhrcHV5Nwp0WlJvc3ZPRjFYNXVMMWZyVkp6SE41akFTRURBYTdoSk5tUTI0a2grZHMvR2UzOWZHRDhwSzMxQ1dobklYZURvCnZLRDd3aXZpL2dTT0J0Y1JXV0x2VThTaXpaa1MzaGdUdzBsU09mNWdldXp2YXNDRVlscXJLRnNzajZjVHpiQ0IKeHkzcmEzV2F6UlROVFc0VG1rSGxDVUM5STNvV1RUeHc1aVF4Ri9JMmtRUW53UjdMM3c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMTguMjM3LjE0Ny4xMDUtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGJEQ0NBbFNnQXdJQkFnSUpBT1VOdFpuZUlZRUNNQTBHQ1NxR1NJYjNEUUVCQlFVQU1HZ3hDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSURBcERZV3hwWm05eWJtbGhNUkl3RUFZRFZRUUhEQWxEYkdGeVpXMXZiblF4Ckd6QVpCZ05WQkFvTUVsQnlhWFpoZEdWbmNtbDBlU0JEYjNKd0xqRVRNQkVHQTFVRUF3d0tLaTVqYldsNExuSnAKY0RBZUZ3MHhPVEF6TURVeE9ETTFORE5hRncweU9UQXpNREl4T0RNMU5ETmFNR2d4Q3pBSkJnTlZCQVlUQWxWVApNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReEd6QVpCZ05WCkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVUTUJFR0ExVUVBd3dLS2k1amJXbDRMbkpwY0RDQ0FTSXcKRFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQVBQMFd5VmtmWkEvQ0VkMkRnS3BjdWRuMG9EaApEd3NqbXg4TEJEV3NVZ1F6eUxyRmlWaWdmVW1VZWZrblVIM2RUSmptaUp0R3FMc2F5Q25XZHFXTEhQSll2RmZzCldZVzBJR0Y5M1VHLzRONVVBV080b2tDM0NZZ0tTaTRla3BmdzJ6Z1pxMGdtYnpUblhjSEY5Z2ZtUTdqSlVLU0UKdEpQU056WHErUFplSlRDOXpKQWI0TGo4UXpIMThyRE04RGFMMnkxbnMwWTJIdTBlZEJGbi9PcWF2QkpLYi91QQptM0FFanFlT2hDN0VRVWpWYW1XbFRCUHQ0MCtCLzZhRkpYNUJZbTJKRmtSc0dCSXlCVkw0Nk12QzAyTWd6VFQ5CmJKSUpmd3FtQmFUcnV3ZW1OZ3pHdTdKazAzaHFxUzFUVUV2U0k2L3g4YlZvYmEzb3JjS2tmOUhzRGpFQ0F3RUEKQWFNWk1CY3dGUVlEVlIwUkJBNHdESUlLS2k1amJXbDRMbkpwY0RBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQQpuZVVvY040QWJjUUFDMStiM1RvOHU1VUdkYUd4aGNHeVpCbEFvZW5SVmRqWEszbFRqc01kTVdiNFFjdGdOZklmClUvenVVbjJteFRtRi9la1AwZ0NDZ3RsZVpyOStEWUtVNWhsWGs4SzEwdUt4R0Q2RXZvaVhaemxmZVV1b3RncDIKcXZJM3lzT20vaHZDZnlFa3FoZkh0YnhqVjdqN3Y3ZVFGUGJ2TmFYYkxhMHlyNEM0dk1LL1owOVVpOUpyWi9aNApjeUlreGZDNi9yT3FBaXJTZElwMDlFR2l3N0dNOGd1SHlnZ0U0SWlackRzbFQ4VjN4SWw5ODVjYkN4U3hlVzFSCnRnSDRyZEVYdVZlOSszMW9KaG1YT0U5dXgyakNvcDl0RUpNZ1dnN0hTdHJKNXBsUGJiK0htam9YM25CTzA0RTUKNm01MlB5ek1OVisyTjIxSVBwcEt3QT09Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA1Mi4xMS4xMzYuMjM4LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURiRENDQWxTZ0F3SUJBZ0lKQU9VTnRabmVJWUVDTUEwR0NTcUdTSWIzRFFFQkJRVUFNR2d4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReApHekFaQmdOVkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVUTUJFR0ExVUVBd3dLS2k1amJXbDRMbkpwCmNEQWVGdzB4T1RBek1EVXhPRE0xTkROYUZ3MHlPVEF6TURJeE9ETTFORE5hTUdneEN6QUpCZ05WQkFZVEFsVlQKTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5WlcxdmJuUXhHekFaQmdOVgpCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFVE1CRUdBMVVFQXd3S0tpNWpiV2w0TG5KcGNEQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFQUDBXeVZrZlpBL0NFZDJEZ0twY3VkbjBvRGgKRHdzam14OExCRFdzVWdRenlMckZpVmlnZlVtVWVma25VSDNkVEpqbWlKdEdxTHNheUNuV2RxV0xIUEpZdkZmcwpXWVcwSUdGOTNVRy80TjVVQVdPNG9rQzNDWWdLU2k0ZWtwZncyemdacTBnbWJ6VG5YY0hGOWdmbVE3akpVS1NFCnRKUFNOelhxK1BaZUpUQzl6SkFiNExqOFF6SDE4ckRNOERhTDJ5MW5zMFkySHUwZWRCRm4vT3FhdkJKS2IvdUEKbTNBRWpxZU9oQzdFUVVqVmFtV2xUQlB0NDArQi82YUZKWDVCWW0ySkZrUnNHQkl5QlZMNDZNdkMwMk1nelRUOQpiSklKZndxbUJhVHJ1d2VtTmd6R3U3SmswM2hxcVMxVFVFdlNJNi94OGJWb2JhM29yY0trZjlIc0RqRUNBd0VBCkFhTVpNQmN3RlFZRFZSMFJCQTR3RElJS0tpNWpiV2w0TG5KcGNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUEKbmVVb2NONEFiY1FBQzErYjNUbzh1NVVHZGFHeGhjR3laQmxBb2VuUlZkalhLM2xUanNNZE1XYjRRY3RnTmZJZgpVL3p1VW4ybXhUbUYvZWtQMGdDQ2d0bGVacjkrRFlLVTVobFhrOEsxMHVLeEdENkV2b2lYWnpsZmVVdW90Z3AyCnF2STN5c09tL2h2Q2Z5RWtxaGZIdGJ4alY3ajd2N2VRRlBidk5hWGJMYTB5cjRDNHZNSy9aMDlVaTlKclovWjQKY3lJa3hmQzYvck9xQWlyU2RJcDA5RUdpdzdHTThndUh5Z2dFNElpWnJEc2xUOFYzeElsOTg1Y2JDeFN4ZVcxUgp0Z0g0cmRFWHVWZTkrMzFvSmhtWE9FOXV4MmpDb3A5dEVKTWdXZzdIU3RySjVwbFBiYitIbWpvWDNuQk8wNEU1CjZtNTJQeXpNTlYrMk4yMUlQcHBLd0E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzQuMjEzLjc5LjMxLS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURiRENDQWxTZ0F3SUJBZ0lKQU9VTnRabmVJWUVDTUEwR0NTcUdTSWIzRFFFQkJRVUFNR2d4Q3pBSkJnTlYKQkFZVEFsVlRNUk13RVFZRFZRUUlEQXBEWVd4cFptOXlibWxoTVJJd0VBWURWUVFIREFsRGJHRnlaVzF2Ym5ReApHekFaQmdOVkJBb01FbEJ5YVhaaGRHVm5jbWwwZVNCRGIzSndMakVUTUJFR0ExVUVBd3dLS2k1amJXbDRMbkpwCmNEQWVGdzB4T1RBek1EVXhPRE0xTkROYUZ3MHlPVEF6TURJeE9ETTFORE5hTUdneEN6QUpCZ05WQkFZVEFsVlQKTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5WlcxdmJuUXhHekFaQmdOVgpCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFVE1CRUdBMVVFQXd3S0tpNWpiV2w0TG5KcGNEQ0NBU0l3CkRRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFQUDBXeVZrZlpBL0NFZDJEZ0twY3VkbjBvRGgKRHdzam14OExCRFdzVWdRenlMckZpVmlnZlVtVWVma25VSDNkVEpqbWlKdEdxTHNheUNuV2RxV0xIUEpZdkZmcwpXWVcwSUdGOTNVRy80TjVVQVdPNG9rQzNDWWdLU2k0ZWtwZncyemdacTBnbWJ6VG5YY0hGOWdmbVE3akpVS1NFCnRKUFNOelhxK1BaZUpUQzl6SkFiNExqOFF6SDE4ckRNOERhTDJ5MW5zMFkySHUwZWRCRm4vT3FhdkJKS2IvdUEKbTNBRWpxZU9oQzdFUVVqVmFtV2xUQlB0NDArQi82YUZKWDVCWW0ySkZrUnNHQkl5QlZMNDZNdkMwMk1nelRUOQpiSklKZndxbUJhVHJ1d2VtTmd6R3U3SmswM2hxcVMxVFVFdlNJNi94OGJWb2JhM29yY0trZjlIc0RqRUNBd0VBCkFhTVpNQmN3RlFZRFZSMFJCQTR3RElJS0tpNWpiV2w0TG5KcGNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUEKbmVVb2NONEFiY1FBQzErYjNUbzh1NVVHZGFHeGhjR3laQmxBb2VuUlZkalhLM2xUanNNZE1XYjRRY3RnTmZJZgpVL3p1VW4ybXhUbUYvZWtQMGdDQ2d0bGVacjkrRFlLVTVobFhrOEsxMHVLeEdENkV2b2lYWnpsZmVVdW90Z3AyCnF2STN5c09tL2h2Q2Z5RWtxaGZIdGJ4alY3ajd2N2VRRlBidk5hWGJMYTB5cjRDNHZNSy9aMDlVaTlKclovWjQKY3lJa3hmQzYvck9xQWlyU2RJcDA5RUdpdzdHTThndUh5Z2dFNElpWnJEc2xUOFYzeElsOTg1Y2JDeFN4ZVcxUgp0Z0g0cmRFWHVWZTkrMzFvSmhtWE9FOXV4MmpDb3A5dEVKTWdXZzdIU3RySjVwbFBiYitIbWpvWDNuQk8wNEU1CjZtNTJQeXpNTlYrMk4yMUlQcHBLd0E9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tcmVnaXN0cmF0aW9uLmRlZmF1bHQuY21peC5yaXAtLS0tLUJFR0lOIENFUlRJRklDQVRFLS0tLS0KTUlJRGtEQ0NBbmlnQXdJQkFnSUpBSm5qb3N1U3NQN2dNQTBHQ1NxR1NJYjNEUUVCQlFVQU1IUXhDekFKQmdOVgpCQVlUQWxWVE1STXdFUVlEVlFRSURBcERZV3hwWm05eWJtbGhNUkl3RUFZRFZRUUhEQWxEYkdGeVpXMXZiblF4Ckd6QVpCZ05WQkFvTUVsQnlhWFpoZEdWbmNtbDBlU0JEYjNKd0xqRWZNQjBHQTFVRUF3d1djbVZuYVhOMGNtRjAKYVc5dUtpNWpiV2w0TG5KcGNEQWVGdzB4T1RBek1EVXlNVFE1TlRaYUZ3MHlPVEF6TURJeU1UUTVOVFphTUhReApDekFKQmdOVkJBWVRBbFZUTVJNd0VRWURWUVFJREFwRFlXeHBabTl5Ym1saE1SSXdFQVlEVlFRSERBbERiR0Z5ClpXMXZiblF4R3pBWkJnTlZCQW9NRWxCeWFYWmhkR1ZuY21sMGVTQkRiM0p3TGpFZk1CMEdBMVVFQXd3V2NtVm4KYVhOMGNtRjBhVzl1S2k1amJXbDRMbkpwY0RDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQwpnZ0VCQU9RS3ZxamRoMzVvK01FQ0JoQ3dvcEp6UGxRTm1xMmlQYmV3Uk50STAyYlVOSzNrTFFVYkZsWWR6TkdaClM0R1lYR2M1TytqZGk4U2x4ODJyMWtkano1UFBDTkZCQVJJc09QL0w4cjNER2VXK3llSmRnQlpqbTFzM3lsa2EKbXQ0QWppcS9iTmp5c1M2TC9XU09wK3NWdW1EeHRCRXpPL1VUVTFPNlFSbnpVcGhMYWlXRU5tRXJHdnNIMENaVgpxMzhJYTU4ay9RakNBenBVY1lpNGoybDFmYjA3eHFGY1FEOEg2U21VTTI5N1V5UW9zRHJwOHVrZElvMzFLb3hyCjRYRG5uTk5zWVN0QzI2dHpITWVLdUoyV2wrM1l6c1N5ZmxmTTJZRWNLRTMxc3FCOURTMzZVa0o4Sjg0ZUxzSE4KSW1HZzNXb2RGQXZpREI2NytqWERiQjMwTmtNQ0F3RUFBYU1sTUNNd0lRWURWUjBSQkJvd0dJSVdjbVZuYVhOMApjbUYwYVc5dUtpNWpiV2w0TG5KcGNEQU5CZ2txaGtpRzl3MEJBUVVGQUFPQ0FRRUFGOW1OemsrZytvNjI2UmxsCnQzZjMvMXFJeVlRcllKMEJqU1dDS1lFRk1DZ1o0SmliQUpqQXZJYWpoVllFUnRsdGZmTStZS2NkRTJrVHBkekoKMFlKdVVuUmZ1djZzVm5YbFZWdWdVVW5kNElPaWdtamJDZE0zMmsxNzBDWU1tMGFpd0d4bDRGck5hOGVpN0FJYQp4L3MxbitzcVdxM0hlVzVMWGpub1ZiK3MzSGVDV0l1TGZjZ3J1cmZ5ZThGbk5oeTE0SEZ6eFZZWWVmSUttMFhMCitEUGxjR0dHbS9QUFl0M3U0YTIrclAzeGFpaGM2NWRUYTB1NXRmL1hQWHRQeFREUEZqMkplUURGeG83UVJSRWIKUEQ4OUN0WW53dVA5MzdDcmt2Q0tyTDBHa1cxRlZpWEtxWlk5RjV1aHhydkxJcHpoYk5ycy9FYnR3ZVkzNVhHTApEQ0NNa2c9PQotLS0tLUVORCBDRVJUSUZJQ0FURS0tLS0tAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABwdWJrZXkxLjIuMy40OjEyMzQBAgNGRkZGRkZGRkZGRkZGRkZGQzkwRkRBQTIyMTY4QzIzNEM0QzY2MjhCODBEQzFDRDEyOTAyNEUwODhBNjdDQzc0MDIwQkJFQTYzQjEzOUIyMjUxNEEwODc5OEUzNDA0RERFRjk1MTlCM0NEM0E0MzFCMzAyQjBBNkRGMjVGMTQzNzRGRTEzNTZENkQ1MUMyNDVFNDg1QjU3NjYyNUU3RUM2RjQ0QzQyRTlBNjM3RUQ2QjBCRkY1Q0I2RjQwNkI3RURFRTM4NkJGQjVBODk5RkE1QUU5RjI0MTE3QzRCMUZFNjQ5Mjg2NjUxRUNFNDVCM0RDMjAwN0NCOEExNjNCRjA1OThEQTQ4MzYxQzU1RDM5QTY5MTYzRkE4RkQyNENGNUY4MzY1NUQyM0RDQTNBRDk2MUM2MkYzNTYyMDg1NTJCQjlFRDUyOTA3NzA5Njk2NkQ2NzBDMzU0RTRBQkM5ODA0RjE3NDZDMDhDQTE4MjE3QzMyOTA1RTQ2MkUzNkNFM0JFMzlFNzcyQzE4MEU4NjAzOUIyNzgzQTJFQzA3QTI4RkI1QzU1REYwNkY0QzUyQzlERTJCQ0JGNjk1NTgxNzE4Mzk5NTQ5N0NFQTk1NkFFNTE1RDIyNjE4OThGQTA1MTAxNTcyOEU1QThBQUNBQTY4RkZGRkZGRkZGRkZGRkZGRjAyN0ZGRkZGRkZGRkZGRkZGRkU0ODdFRDUxMTBCNDYxMUE2MjYzMzE0NUMwNkUwRTY4OTQ4MTI3MDQ0NTMzRTYzQTAxMDVERjUzMUQ4OUNEOTEyOEE1MDQzQ0M3MUEwMjZFRjdDQThDRDlFNjlEMjE4RDk4MTU4NTM2RjkyRjhBMUJBN0YwOUFCNkI2QThFMTIyRjI0MkRBQkIzMTJGM0Y2MzdBMjYyMTc0RDMxQkY2QjU4NUZGQUU1QjdBMDM1QkY2RjcxQzM1RkRBRDQ0Q0ZEMkQ3NEY5MjA4QkUyNThGRjMyNDk0MzMyOEY2NzIyRDlFRTEwMDNFNUM1MEIxREY4MkNDNkQyNDFCMEUyQUU5Q0QzNDhCMUZENDdFOTI2N0FGQzFCMkFFOTFFRTUxRDZDQjBFMzE3OUFCMTA0MkE5NURDRjZBOTQ4M0I4NEI0QjM2QjM4NjFBQTcyNTVFNEMwMjc4QkEzNjA0NjUwQzEwQkUxOTQ4MkYyMzE3MUI2NzFERjFDRjNCOTYwQzA3NDMwMUNEOTNDMUQxNzYwM0QxNDdEQUUyQUVGODM3QTYyOTY0RUYxNUU1RkI0QUFDMEI4QzFDQ0FBNEJFNzU0QUI1NzI4QUU5MTMwQzRDN0QwMjg4MEFCOTQ3MkQ0NTU2NTUzNDdGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGRkZGQzkwRkRBQTIyMTY4QzIzNEM0QzY2MjhCODBEQzFDRDEyOTAyNEUwODhBNjdDQzc0MDIwQkJFQTYzQjEzOUIyMjUxNEEwODc5OEUzNDA0RERFRjk1MTlCM0NEM0E0MzFCMzAyQjBBNkRGMjVGMTQzNzRGRTEzNTZENkQ1MUMyNDVFNDg1QjU3NjYyNUU3RUM2RjQ0QzQyRTlBNjM3RUQ2QjBCRkY1Q0I2RjQwNkI3RURFRTM4NkJGQjVBODk5RkE1QUU5RjI0MTE3QzRCMUZFNjQ5Mjg2NjUxRUNFNDVCM0RDMjAwN0NCOEExNjNCRjA1OThEQTQ4MzYxQzU1RDM5QTY5MTYzRkE4RkQyNENGNUY4MzY1NUQyM0RDQTNBRDk2MUM2MkYzNTYyMDg1NTJCQjlFRDUyOTA3NzA5Njk2NkQ2NzBDMzU0RTRBQkM5ODA0RjE3NDZDMDhDQTE4MjE3QzMyOTA1RTQ2MkUzNkNFM0JFMzlFNzcyQzE4MEU4NjAzOUIyNzgzQTJFQzA3QTI4RkI1QzU1REYwNkY0QzUyQzlERTJCQ0JGNjk1NTgxNzE4Mzk5NTQ5N0NFQTk1NkFFNTE1RDIyNjE4OThGQTA1MTAxNTcyOEU1QThBQUNBQTY4RkZGRkZGRkZGRkZGRkZGRjAyN0ZGRkZGRkZGRkZGRkZGRkU0ODdFRDUxMTBCNDYxMUE2MjYzMzE0NUMwNkUwRTY4OTQ4MTI3MDQ0NTMzRTYzQTAxMDVERjUzMUQ4OUNEOTEyOEE1MDQzQ0M3MUEwMjZFRjdDQThDRDlFNjlEMjE4RDk4MTU4NTM2RjkyRjhBMUJBN0YwOUFCNkI2QThFMTIyRjI0MkRBQkIzMTJGM0Y2MzdBMjYyMTc0RDMxQkY2QjU4NUZGQUU1QjdBMDM1QkY2RjcxQzM1RkRBRDQ0Q0ZEMkQ3NEY5MjA4QkUyNThGRjMyNDk0MzMyOEY2NzIyRDlFRTEwMDNFNUM1MEIxREY4MkNDNkQyNDFCMEUyQUU5Q0QzNDhCMUZENDdFOTI2N0FGQzFCMkFFOTFFRTUxRDZDQjBFMzE3OUFCMTA0MkE5NURDRjZBOTQ4M0I4NEI0QjM2QjM4NjFBQTcyNTVFNEMwMjc4QkEzNjA0NjUwQzEwQkUxOTQ4MkYyMzE3MUI2NzFERjFDRjNCOTYwQzA3NDMwMUNEOTNDMUQxNzYwM0QxNDdEQUUyQUVGODM3QTYyOTY0RUYxNUU1RkI0QUFDMEI4QzFDQ0FBNEJFNzU0QUI1NzI4QUU5MTMwQzRDN0QwMjg4MEFCOTQ3MkQ0NTU2NTUzNDdGRkZGRkZGRkZGRkZGRkY=")
 )
 
-// Test that DecodeNDF() fills all the fields with the proper data.
-func TestDecodeNDF(t *testing.T) {
+// Test that Unmarshal() fills all the fields with the proper data.
+func TestUnmarshal(t *testing.T) {
 	var received, expected string
 
-	jsonData, signature, err := DecodeNDF(ExampleNDF)
+	jsonData, err := Unmarshal([]byte(ExampleNDF))
 	if err != nil {
-		t.Errorf("DecodeNDF() unexpectedly produced an error"+
-			"\n\treceived: %#v\n\texpected: %#v",
-			err, nil)
+		t.Errorf("Unmarshal() returned an error: %+v", err)
 	}
 
 	timestamp, _ := time.Parse(time.RFC3339, "2019-06-04T20:48:48-07:00")
 
 	/* Ensure fields are populated with the correct data */
 
-	// Signature
-	if !bytes.Equal(signature, SignatureBytes) {
-		t.Errorf("DecodeNDF() did not return the correct signature"+
-			"\n\treceived: %v\n\texpected: %v",
-			signature, SignatureBytes)
-	}
-
 	// Timestamp
+	fmt.Printf("%s\n", jsonData.Timestamp)
 	if !jsonData.Timestamp.Equal(timestamp) {
-		t.Errorf("DecodeNDF() did not correctly set Timestamp"+
+		t.Errorf("Unmarshal() did not correctly set Timestamp"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			jsonData.Timestamp, timestamp)
 	}
@@ -119,13 +108,13 @@ func TestDecodeNDF(t *testing.T) {
 
 	for i, val := range gateways {
 		if jsonData.Gateways[i].Address != val.Address {
-			t.Errorf("DecodeNDF() did not correctly set Gateways[%d].address"+
+			t.Errorf("Unmarshal() did not correctly set Gateways[%d].address"+
 				"\n\treceived: %#v\n\texpected: %#v",
 				i, jsonData.Gateways[i].Address, val.Address)
 		}
 
 		if jsonData.Gateways[i].TlsCertificate != val.TlsCertificate {
-			t.Errorf("DecodeNDF() did not correctly set Gateways[%d].TlsCertificate"+
+			t.Errorf("Unmarshal() did not correctly set Gateways[%d].TlsCertificate"+
 				"\n\treceived: %#v\n\texpected: %#v",
 				i, jsonData.Gateways[i].TlsCertificate, val.TlsCertificate)
 		}
@@ -141,19 +130,19 @@ func TestDecodeNDF(t *testing.T) {
 
 	for i, val := range nodes {
 		if !reflect.DeepEqual(jsonData.Nodes[i].ID, val.ID) {
-			t.Errorf("DecodeNDF() did not correctly set Nodes[%d] ID"+
+			t.Errorf("Unmarshal() did not correctly set Nodes[%d] ID"+
 				"\n\treceived: %#v\n\texpected: %#v",
 				i, jsonData.Nodes[i].ID, val.ID)
 		}
 
 		if jsonData.Nodes[i].Address != val.Address {
-			t.Errorf("DecodeNDF() did not correctly set Nodes[%d].Address"+
+			t.Errorf("Unmarshal() did not correctly set Nodes[%d].Address"+
 				"\n\treceived: %#v\n\texpected: %#v",
 				i, jsonData.Nodes[i].Address, val.Address)
 		}
 
 		if jsonData.Nodes[i].TlsCertificate != val.TlsCertificate {
-			t.Errorf("DecodeNDF() did not correctly set Nodes[%d].TlsCertificate"+
+			t.Errorf("Unmarshal() did not correctly set Nodes[%d].TlsCertificate"+
 				"\n\treceived: %#v\n\texpected: %#v",
 				i, jsonData.Nodes[i].TlsCertificate, val.TlsCertificate)
 		}
@@ -163,7 +152,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.Registration.Address
 	expected = "registration.default.cmix.rip"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set Registration.Address"+
+		t.Errorf("Unmarshal() did not correctly set Registration.Address"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -171,7 +160,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.Registration.TlsCertificate
 	expected = "-----BEGIN CERTIFICATE-----\nMIIDkDCCAnigAwIBAgIJAJnjosuSsP7gMA0GCSqGSIb3DQEBBQUAMHQxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEfMB0GA1UEAwwWcmVnaXN0cmF0\naW9uKi5jbWl4LnJpcDAeFw0xOTAzMDUyMTQ5NTZaFw0yOTAzMDIyMTQ5NTZaMHQx\nCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFy\nZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEfMB0GA1UEAwwWcmVn\naXN0cmF0aW9uKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBAOQKvqjdh35o+MECBhCwopJzPlQNmq2iPbewRNtI02bUNK3kLQUbFlYdzNGZ\nS4GYXGc5O+jdi8Slx82r1kdjz5PPCNFBARIsOP/L8r3DGeW+yeJdgBZjm1s3ylka\nmt4Ajiq/bNjysS6L/WSOp+sVumDxtBEzO/UTU1O6QRnzUphLaiWENmErGvsH0CZV\nq38Ia58k/QjCAzpUcYi4j2l1fb07xqFcQD8H6SmUM297UyQosDrp8ukdIo31Koxr\n4XDnnNNsYStC26tzHMeKuJ2Wl+3YzsSyflfM2YEcKE31sqB9DS36UkJ8J84eLsHN\nImGg3WodFAviDB67+jXDbB30NkMCAwEAAaMlMCMwIQYDVR0RBBowGIIWcmVnaXN0\ncmF0aW9uKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAF9mNzk+g+o626Rll\nt3f3/1qIyYQrYJ0BjSWCKYEFMCgZ4JibAJjAvIajhVYERtltffM+YKcdE2kTpdzJ\n0YJuUnRfuv6sVnXlVVugUUnd4IOigmjbCdM32k170CYMm0aiwGxl4FrNa8ei7AIa\nx/s1n+sqWq3HeW5LXjnoVb+s3HeCWIuLfcgrurfye8FnNhy14HFzxVYYefIKm0XL\n+DPlcGGGm/PPYt3u4a2+rP3xaihc65dTa0u5tf/XPXtPxTDPFj2JeQDFxo7QRREb\nPD89CtYnwuP937CrkvCKrL0GkW1FViXKqZY9F5uhxrvLIpzhbNrs/EbtweY35XGL\nDCCMkg==\n-----END CERTIFICATE-----"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set Registration.TlsCertificate"+
+		t.Errorf("Unmarshal() did not correctly set Registration.TlsCertificate"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -180,7 +169,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.Notification.Address
 	expected = "notification.default.cmix.rip"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set Registration.Address"+
+		t.Errorf("Unmarshal() did not correctly set Registration.Address"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -188,7 +177,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.Notification.TlsCertificate
 	expected = "-----BEGIN CERTIFICATE-----\nMIIDkDCCAnigAwIBAgIJAJnjosuSsP7gMA0GCSqGSIb3DQEBBQUAMHQxCzAJBgNV\nBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFyZW1vbnQx\nGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEfMB0GA1UEAwwWcmVnaXN0cmF0\naW9uKi5jbWl4LnJpcDAeFw0xOTAzMDUyMTQ5NTZaFw0yOTAzMDIyMTQ5NTZaMHQx\nCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRIwEAYDVQQHDAlDbGFy\nZW1vbnQxGzAZBgNVBAoMElByaXZhdGVncml0eSBDb3JwLjEfMB0GA1UEAwwWcmVn\naXN0cmF0aW9uKi5jbWl4LnJpcDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC\nggEBAOQKvqjdh35o+MECBhCwopJzPlQNmq2iPbewRNtI02bUNK3kLQUbFlYdzNGZ\nS4GYXGc5O+jdi8Slx82r1kdjz5PPCNFBARIsOP/L8r3DGeW+yeJdgBZjm1s3ylka\nmt4Ajiq/bNjysS6L/WSOp+sVumDxtBEzO/UTU1O6QRnzUphLaiWENmErGvsH0CZV\nq38Ia58k/QjCAzpUcYi4j2l1fb07xqFcQD8H6SmUM297UyQosDrp8ukdIo31Koxr\n4XDnnNNsYStC26tzHMeKuJ2Wl+3YzsSyflfM2YEcKE31sqB9DS36UkJ8J84eLsHN\nImGg3WodFAviDB67+jXDbB30NkMCAwEAAaMlMCMwIQYDVR0RBBowGIIWcmVnaXN0\ncmF0aW9uKi5jbWl4LnJpcDANBgkqhkiG9w0BAQUFAAOCAQEAF9mNzk+g+o626Rll\nt3f3/1qIyYQrYJ0BjSWCKYEFMCgZ4JibAJjAvIajhVYERtltffM+YKcdE2kTpdzJ\n0YJuUnRfuv6sVnXlVVugUUnd4IOigmjbCdM32k170CYMm0aiwGxl4FrNa8ei7AIa\nx/s1n+sqWq3HeW5LXjnoVb+s3HeCWIuLfcgrurfye8FnNhy14HFzxVYYefIKm0XL\n+DPlcGGGm/PPYt3u4a2+rP3xaihc65dTa0u5tf/XPXtPxTDPFj2JeQDFxo7QRREb\nPD89CtYnwuP937CrkvCKrL0GkW1FViXKqZY9F5uhxrvLIpzhbNrs/EbtweY35XGL\nDCCMkg==\n-----END CERTIFICATE-----"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set Registration.TlsCertificate"+
+		t.Errorf("Unmarshal() did not correctly set Registration.TlsCertificate"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -197,12 +186,24 @@ func TestDecodeNDF(t *testing.T) {
 	expectedUdbId := make([]byte, 32)
 	expectedUdbId[0] = 1
 	if !bytes.Equal(jsonData.UDB.ID, expectedUdbId) {
-		t.Errorf("DecodeNDF() did not correctly set jsonData.UDB.ID"+
+		t.Errorf("Unmarshal() did not correctly set UDB.ID"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			jsonData.UDB.ID, expectedUdbId)
 	}
+
+	if !bytes.Equal(jsonData.UDB.DhPubKey, []byte{1, 2, 3}) {
+		t.Errorf("Unmarshal() did not correctly set UDB.DhPubKey"+
+			"\n\treceived: %+v\n\texpected: %+v",
+			jsonData.UDB.DhPubKey, []byte{1, 2, 3})
+	}
+
+	if jsonData.UDB.Address != "1.2.3.4:1234" {
+		t.Errorf("Unmarshal() did not correctly set UDB.DhPubKey"+
+			"\n\treceived: %s\n\texpected: %s",
+			jsonData.UDB.Address, "1.2.3.4:1234")
+	}
 	if !reflect.DeepEqual(jsonData.UDB.Cert, "pubkey") {
-		t.Errorf("DecodeNDF() did not correctly set jsonData.UDB.Cert"+
+		t.Errorf("Unmarshal() did not correctly set UDB.Cert"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			jsonData.UDB.Cert, "pubkey")
 	}
@@ -211,7 +212,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.E2E.Prime
 	expected = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set E2E.Prime"+
+		t.Errorf("Unmarshal() did not correctly set E2E.Prime"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -219,7 +220,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.E2E.SmallPrime
 	expected = "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68948127044533E63A0105DF531D89CD9128A5043CC71A026EF7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6F71C35FDAD44CFD2D74F9208BE258FF324943328F6722D9EE1003E5C50B1DF82CC6D241B0E2AE9CD348B1FD47E9267AFC1B2AE91EE51D6CB0E3179AB1042A95DCF6A9483B84B4B36B3861AA7255E4C0278BA3604650C10BE19482F23171B671DF1CF3B960C074301CD93C1D17603D147DAE2AEF837A62964EF15E5FB4AAC0B8C1CCAA4BE754AB5728AE9130C4C7D02880AB9472D455655347FFFFFFFFFFFFFFF"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set E2E.Small_prime"+
+		t.Errorf("Unmarshal() did not correctly set E2E.Small_prime"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -227,7 +228,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.E2E.Generator
 	expected = "02"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set E2E.Generator"+
+		t.Errorf("Unmarshal() did not correctly set E2E.Generator"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -236,7 +237,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.CMIX.Prime
 	expected = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3DC2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F83655D23DCA3AD961C62F356208552BB9ED529077096966D670C354E4ABC9804F1746C08CA18217C32905E462E36CE3BE39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9DE2BCBF6955817183995497CEA956AE515D2261898FA051015728E5A8AACAA68FFFFFFFFFFFFFFFF"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set CMIX.Prime"+
+		t.Errorf("Unmarshal() did not correctly set CMIX.Prime"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -244,7 +245,7 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.CMIX.SmallPrime
 	expected = "7FFFFFFFFFFFFFFFE487ED5110B4611A62633145C06E0E68948127044533E63A0105DF531D89CD9128A5043CC71A026EF7CA8CD9E69D218D98158536F92F8A1BA7F09AB6B6A8E122F242DABB312F3F637A262174D31BF6B585FFAE5B7A035BF6F71C35FDAD44CFD2D74F9208BE258FF324943328F6722D9EE1003E5C50B1DF82CC6D241B0E2AE9CD348B1FD47E9267AFC1B2AE91EE51D6CB0E3179AB1042A95DCF6A9483B84B4B36B3861AA7255E4C0278BA3604650C10BE19482F23171B671DF1CF3B960C074301CD93C1D17603D147DAE2AEF837A62964EF15E5FB4AAC0B8C1CCAA4BE754AB5728AE9130C4C7D02880AB9472D455655347FFFFFFFFFFFFFFF"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set CMIX.Small_prime"+
+		t.Errorf("Unmarshal() did not correctly set CMIX.Small_prime"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
@@ -252,89 +253,25 @@ func TestDecodeNDF(t *testing.T) {
 	received = jsonData.CMIX.Generator
 	expected = "02"
 	if received != expected {
-		t.Errorf("DecodeNDF() did not correctly set CMIX.Generator"+
+		t.Errorf("Unmarshal() did not correctly set CMIX.Generator"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			received, expected)
 	}
 
 }
 
-// Tests that DecodeNDF() returns an error when Unmarshal() returns an error.
-func TestDecodeNDF_ErrUnmarshal(t *testing.T) {
-	jsonData, signature, err := DecodeNDF("test" + ExampleNDF)
-
-	if jsonData != nil {
-		t.Errorf("DecodeNDF() did not corectly return nil NetworkDefinition on error"+
-			"\n\treceived: %#v\n\texpected: %#v", jsonData, nil)
-	}
-
-	if !bytes.Equal(signature, nil) {
-		t.Errorf("DecodeNDF() did not corectly return the signature on error"+
-			"\n\treceived: %v\n\texpected: %v", signature, nil)
-	}
+// Tests that Unmarshal() returns an error when Unmarshal() returns an error.
+func TestUnmarshal_ErrUnmarshal(t *testing.T) {
+	_, err := Unmarshal([]byte("{\"gateways\": 5}"))
 
 	if err == nil {
-		t.Errorf("DecodeNDF() did not issue the expected error"+
-			"\n\treceived: %#v\n\texpected: %#v", err, errors.New(""))
-	}
-}
-
-// Tests that separate() throws an error when the signature is not base64.
-func TestDecodeNDF_ErrDecode(t *testing.T) {
-	jsonData, signature, err := DecodeNDF(ExampleJSON + "\nhello")
-
-	if jsonData != nil {
-		t.Errorf("DecodeNDF() did not corectly return nil NetworkDefinition on error"+
-			"\n\treceived: %#v\n\texpected: %#v", jsonData, nil)
-	}
-
-	if !bytes.Equal(signature, nil) {
-		t.Errorf("DecodeNDF() did not corectly return the signature on error"+
-			"\n\treceived: %v\n\texpected: %v", signature, nil)
-	}
-
-	if err == nil {
-		t.Errorf("separate() did not issue the expected error"+
-			"\n\treceived: %#v\n\texpected: %#v", err, errors.New(""))
-	}
-}
-
-// Tests that separate() correctly splits the JSON data from the string.
-func TestSeparate(t *testing.T) {
-	jsonData, signature := separate(ExampleNDF)
-
-	if jsonData != strings.TrimSpace(ExampleJSON) {
-		t.Errorf("separate() did not corectly seperate the JSON data"+
-			"\n\treceived: %#v\n\texpected: %#v",
-			jsonData, strings.TrimSpace(ExampleJSON))
-	}
-
-	if signature != strings.TrimSpace(ExampleSignature) {
-		t.Errorf("DecodeNDF() did not corectly return the signature"+
-			"\n\treceived: %#v\n\texpected: %#v",
-			signature, strings.TrimSpace(ExampleSignature))
-	}
-}
-
-// Tests that separate() returns the JSON string with an empty signature when
-// the NDF file does not have at least two lines.
-func TestSeparate_ErrorLines(t *testing.T) {
-	jsonData, signature := separate(ExampleJSON)
-
-	if jsonData != ExampleJSON {
-		t.Errorf("separate() did not return the JSON string on empty signature"+
-			"\n\treceived: %#v\n\texpected: %#v", jsonData, "")
-	}
-
-	if signature != "" {
-		t.Errorf("DecodeNDF() did not corectly return an empty signature"+
-			"\n\treceived: %#v\n\texpected: %#v", signature, "")
+		t.Errorf("Unmarshal() did not return an error for invalid JSON.")
 	}
 }
 
 // Tests the consistency of Serialize().
 func TestNetworkDefinition_Serialize(t *testing.T) {
-	ndf, _, _ := DecodeNDF(ExampleNDF)
+	ndf, _ := Unmarshal([]byte(ExampleNDF))
 
 	ndfBytes := ndf.Serialize()
 	if !bytes.Equal(ndfBytes, JsonBytes) {
@@ -345,7 +282,7 @@ func TestNetworkDefinition_Serialize(t *testing.T) {
 
 // Happy path
 func TestStripNdf(t *testing.T) {
-	ndf, _, err := DecodeNDF(ExampleNDF)
+	ndf, err := Unmarshal([]byte(ExampleNDF))
 	if err != nil {
 		t.Errorf("Failed to decode ndf for testing: %+v", err)
 	}
@@ -371,9 +308,9 @@ func TestStripNdf(t *testing.T) {
 }
 
 func TestNetworkDefinition_Marshal(t *testing.T) {
-	jsonData, _, err := DecodeNDF(ExampleNDF)
+	jsonData, err := Unmarshal([]byte(ExampleNDF))
 	if err != nil {
-		t.Errorf("DecodeNDF() unexpectedly produced an error"+
+		t.Errorf("Unmarshal() unexpectedly produced an error"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			err, nil)
 	}
@@ -396,9 +333,9 @@ func TestNetworkDefinition_Marshal(t *testing.T) {
 
 // Happy path: this finds an id in the hardcoded/global ExampleNDF
 func TestGetNodeId(t *testing.T) {
-	jsonData, _, err := DecodeNDF(ExampleNDF)
+	jsonData, err := Unmarshal([]byte(ExampleNDF))
 	if err != nil {
-		t.Errorf("DecodeNDF() unexpectedly produced an error"+
+		t.Errorf("Unmarshal() unexpectedly produced an error"+
 			"\n\treceived: %#v\n\texpected: %#v",
 			err, nil)
 	}
diff --git a/netTime/timeNow.go b/netTime/timeNow.go
new file mode 100644
index 0000000000000000000000000000000000000000..a024cc7ffa7c9c7344cdd7497fba8d56a9a76966
--- /dev/null
+++ b/netTime/timeNow.go
@@ -0,0 +1,20 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+// Package netTime provides a custom time function that should provide the
+// current accurate time used by the network from a custom time service.
+package netTime
+
+import (
+	"time"
+)
+
+type NowFunc func() time.Time
+
+// Now returns the current accurate time. The function must be set an accurate
+// time service that returns the current time with an accuracy of +/- 300 ms.
+var Now NowFunc = time.Now
diff --git a/netTime/timeNow_test.go b/netTime/timeNow_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c648569cf158dcc2d32e65d75c4bbae8a9a60c7
--- /dev/null
+++ b/netTime/timeNow_test.go
@@ -0,0 +1,40 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package netTime
+
+import (
+	"testing"
+	"time"
+)
+
+// Happy path: tests that Now() returns time.Now() if it is unset.
+func TestNow(t *testing.T) {
+	expectedTime := time.Now().Round(time.Millisecond)
+	receivedTime := Now().Round(time.Millisecond)
+
+	if !expectedTime.Equal(receivedTime) {
+		t.Errorf("Returned incorrect time.\nexpected: %s\nreceived: %s",
+			expectedTime, receivedTime)
+	}
+}
+
+// Happy path: tests that setting Now works.
+func TestNow_Set(t *testing.T) {
+	expectedTime := time.Now()
+	testNow := func() time.Time {
+		return expectedTime
+	}
+
+	Now = testNow
+
+	now := Now()
+	if !Now().Equal(expectedTime) {
+		t.Errorf("Returned incorrect time.\nexpected: %s\nreceived: %s",
+			expectedTime, now)
+	}
+}