diff --git a/interfaces/networkManager.go b/interfaces/networkManager.go
index c89bd221efbf503410151c991c87bc825dd393e5..34ab130eaaae9e1953cb936262f2f2b1a713a91f 100644
--- a/interfaces/networkManager.go
+++ b/interfaces/networkManager.go
@@ -8,7 +8,6 @@
 package interfaces
 
 import (
-	"encoding/base64"
 	"gitlab.com/elixxir/client/interfaces/message"
 	"gitlab.com/elixxir/client/interfaces/params"
 	"gitlab.com/elixxir/client/network/gateway"
@@ -151,15 +150,8 @@ type IdentityParams struct {
 	Ephemeral bool
 }
 
-type Preimage []byte
-
-// key returns the key used to identify the Preimage in a map.
-func (pi Preimage) String() string {
-	return base64.StdEncoding.EncodeToString(pi)
-}
-
 type Trigger struct {
-	Preimage Preimage
+	Preimage []byte
 	Type     string
 	Source   []byte
 }
@@ -172,6 +164,7 @@ type MessageProcessorFP interface {
 type MessageProcessorTrigger interface {
 	Process(message format.Message, preimage []byte, Type string, source []byte)
 	Equals(trigger MessageProcessorTrigger) bool
+	String() string
 }
 
 //type Ratchet interface {
diff --git a/network/triggers.go b/network/triggers.go
index 2e61ee188de4c7ec6cb97f2dd0d6a38165221d64..5b758c70c722ea0f7859f6797040a2fb1b2a1096 100644
--- a/network/triggers.go
+++ b/network/triggers.go
@@ -8,11 +8,33 @@
 package network
 
 import (
+	"encoding/base64"
 	"github.com/pkg/errors"
 	"gitlab.com/elixxir/client/interfaces"
+	fingerprint2 "gitlab.com/elixxir/crypto/fingerprint"
 	"sync"
 )
 
+/* Trigger - predefined hash based tags appended to all cmix messages
+which, though trial hashing, are used to determine if a message applies
+to this client
+
+Triggers are used for 2 purposes -  can be processed by the notifications system,
+or can be used to implement custom non fingerprint processing of payloads.
+I.E. key negotiation, broadcast negotiation
+
+A tag is appended to the message of the format tag = H(H(messageContents),preimage)
+and trial hashing is used to determine if a message adheres to a tag.
+WARNING: If a preiamge is known by an adversary, they can determine which messages
+are for the client.
+
+Due to the extra overhead of trial hashing, triggers are processed after fingerprints.
+If a fingerprint match occurs on the message, triggers will not be handled.
+
+Triggers are ephemeral to the session. When starting a new client, all triggers must be
+re-added before StartNetworkFollower is called.
+*/
+
 type Triggers struct {
 	triggers map[string][]*Trigger
 	sync.RWMutex
@@ -29,10 +51,22 @@ func NewTriggers() *Triggers {
 }
 
 func (t *Triggers) Lookup(identityFp,
-	ecrMsgContents []byte) (*Trigger, bool) {
+	ecrMsgContents []byte) ([]*Trigger, bool) {
 	t.RLock()
 	defer t.RUnlock()
 
+	for preimage, triggers := range t.triggers {
+		preimageBytes, err := unmarshalPreimage(preimage)
+		if err != nil {
+			// fixme: panic here, this error would mean bad data is in the map
+		}
+
+		if fingerprint2.CheckIdentityFP(identityFp, ecrMsgContents, preimageBytes) {
+			return triggers, true
+		}
+	}
+
+	return nil, false
 }
 
 // Add - Adds a trigger which can call a message
@@ -47,19 +81,20 @@ func (t *Triggers) Add(trigger interfaces.Trigger,
 	t.Lock()
 	defer t.Unlock()
 
-	preimage := trigger.Preimage.String()
+	marshalledPreimage := marshalPreimage(trigger.Preimage)
 
 	newTrigger := &Trigger{
 		Trigger:                 trigger,
 		MessageProcessorTrigger: response,
 	}
 
-	if existingTriggers, exists := t.triggers[preimage]; exists {
-		t.triggers[preimage] = append(existingTriggers, newTrigger)
+	if existingTriggers, exists := t.triggers[marshalledPreimage]; exists {
+		// fixme Should there be a check if this response exists already?
+		t.triggers[marshalledPreimage] = append(existingTriggers, newTrigger)
 		return nil
 	}
 
-	t.triggers[preimage] = []*Trigger{newTrigger}
+	t.triggers[marshalledPreimage] = []*Trigger{newTrigger}
 
 	return nil
 }
@@ -68,26 +103,45 @@ func (t *Triggers) Add(trigger interfaces.Trigger,
 // the entire preimage is removed. If there is more than one response, only
 // the given response is removed. If nil is passed in for response,
 // all triggers for the preimage will be removed.
-func (t *Triggers) RemoveTrigger(preimage interfaces.Preimage,
+func (t *Triggers) RemoveTrigger(preimage []byte,
 	response interfaces.MessageProcessorTrigger) error {
 	t.Lock()
 	defer t.Unlock()
 
-	triggers, exists := t.triggers[preimage.String()]
+	marshalledPreimage := marshalPreimage(preimage)
+
+	triggers, exists := t.triggers[marshalledPreimage]
 	if !exists {
-		return errors.Errorf("No triggers exist with preimage %q", preimage.String())
+		return errors.Errorf("No trigger with preimage %q found",
+			marshalledPreimage)
 	}
 
 	if response == nil {
-		delete(t.triggers, preimage.String())
+		delete(t.triggers, marshalledPreimage)
 		return nil
 	}
 
 	for _, trigger := range triggers {
 		if trigger.Equals(response) {
-			delete(t.triggers, trigger.Preimage.String())
+			delete(t.triggers, marshalPreimage(trigger.Preimage))
+			return nil
 		}
 	}
 
-	return nil
+	return errors.Errorf("No response (%q) exists with preimage %q",
+		response.String(), marshalledPreimage)
+}
+
+// fixme: maybe make preimage a type or struct and place this in primitives?
+func marshalPreimage(pi []byte) string {
+	return base64.StdEncoding.EncodeToString(pi)
+}
+
+func unmarshalPreimage(data string) ([]byte, error) {
+	decoded, err := base64.StdEncoding.DecodeString(data)
+	if err != nil {
+		return nil, err
+	}
+
+	return decoded, nil
 }
diff --git a/network/triggers_test.go b/network/triggers_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..60caace571619a36dba468204a2d6dda540a0129
--- /dev/null
+++ b/network/triggers_test.go
@@ -0,0 +1,8 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package network