diff --git a/api/client.go b/api/client.go
index fb1e81dd3401c6593c42adcb686225773c7a1105..eb5ee92ca9ebecea79fcceec8b3b730285448b95 100644
--- a/api/client.go
+++ b/api/client.go
@@ -20,7 +20,6 @@ import (
 	"gitlab.com/elixxir/primitives/switchboard"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/comms/connect"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
 	goio "io"
 	"time"
@@ -101,7 +100,9 @@ func Register(registrationCode string, gwAddr string,
 		nk[i] = *nodekeys
 	}
 
-	nus := user.NewSession(u, gwAddr, nk, cyclic.NewIntFromBytes([]byte("this is not a real public key")))
+	grp := crypto.InitCrypto()
+
+	nus := user.NewSession(u, gwAddr, nk, grp.NewIntFromBytes([]byte("this is not a real public key")), grp)
 
 	_, err = payment.CreateWallet(nus, mint)
 	if err != nil {
diff --git a/api/client_test.go b/api/client_test.go
index 89e81dfc47035b682fdc090e1521e85718531a27..3a3aa7789e1c65d19de17cf62da0980b94b90708 100644
--- a/api/client_test.go
+++ b/api/client_test.go
@@ -13,13 +13,12 @@ import (
 	"github.com/golang/protobuf/proto"
 	"gitlab.com/elixxir/client/cmixproto"
 	"gitlab.com/elixxir/client/globals"
+	"gitlab.com/elixxir/client/parse"
 	"gitlab.com/elixxir/client/user"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
+	"reflect"
 	"testing"
 	"time"
-	"reflect"
-	"gitlab.com/elixxir/client/parse"
 )
 
 func TestRegistrationGob(t *testing.T) {
@@ -67,7 +66,8 @@ func VerifyRegisterGobUser(t *testing.T) {
 }
 
 func VerifyRegisterGobKeys(t *testing.T) {
-	if Session.GetPublicKey().Cmp(cyclic.NewIntFromBytes([]byte(
+	grp := Session.Grp
+	if Session.GetPublicKey().Cmp(grp.NewIntFromBytes([]byte(
 		"this is not a real public key"))) != 0 {
 		t.Errorf("Public key was %v, expected %v",
 			string(Session.GetPublicKey().Bytes()),
@@ -75,7 +75,7 @@ func VerifyRegisterGobKeys(t *testing.T) {
 	}
 	h := sha256.New()
 	h.Write([]byte(string(30005)))
-	expectedTransmissionRecursiveKey := cyclic.NewIntFromBytes(h.Sum(nil))
+	expectedTransmissionRecursiveKey := grp.NewIntFromBytes(h.Sum(nil))
 	if Session.GetKeys()[0].TransmissionKeys.Recursive.Cmp(
 		expectedTransmissionRecursiveKey) != 0 {
 		t.Errorf("Transmission recursive key was %v, expected %v",
@@ -84,7 +84,7 @@ func VerifyRegisterGobKeys(t *testing.T) {
 	}
 	h = sha256.New()
 	h.Write([]byte(string(20005)))
-	expectedTransmissionBaseKey := cyclic.NewIntFromBytes(h.Sum(nil))
+	expectedTransmissionBaseKey := grp.NewIntFromBytes(h.Sum(nil))
 	if Session.GetKeys()[0].TransmissionKeys.Base.Cmp(
 		expectedTransmissionBaseKey) != 0 {
 		t.Errorf("Transmission base key was %v, expected %v",
@@ -93,7 +93,7 @@ func VerifyRegisterGobKeys(t *testing.T) {
 	}
 	h = sha256.New()
 	h.Write([]byte(string(50005)))
-	expectedReceptionRecursiveKey := cyclic.NewIntFromBytes(h.Sum(nil))
+	expectedReceptionRecursiveKey := grp.NewIntFromBytes(h.Sum(nil))
 	if Session.GetKeys()[0].ReceptionKeys.Recursive.Cmp(
 		expectedReceptionRecursiveKey) != 0 {
 		t.Errorf("Reception recursive key was %v, expected %v",
@@ -102,7 +102,7 @@ func VerifyRegisterGobKeys(t *testing.T) {
 	}
 	h = sha256.New()
 	h.Write([]byte(string(40005)))
-	expectedReceptionBaseKey := cyclic.NewIntFromBytes(h.Sum(nil))
+	expectedReceptionBaseKey := grp.NewIntFromBytes(h.Sum(nil))
 	if Session.GetKeys()[0].ReceptionKeys.Base.Cmp(
 		expectedReceptionBaseKey) != 0 {
 		t.Errorf("Reception base key was %v, expected %v",
diff --git a/api/mockserver_test.go b/api/mockserver_test.go
index 1c6776a91e72a66835ce9b228b17a32f0792596c..dab897a99392ec50c4c77991ac47b2876e872abf 100644
--- a/api/mockserver_test.go
+++ b/api/mockserver_test.go
@@ -15,7 +15,6 @@ import (
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/comms/gateway"
 	pb "gitlab.com/elixxir/comms/mixmessages"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
 	"math/rand"
 	"os"
@@ -130,9 +129,10 @@ func SetNulKeys() {
 	// Set the transmit keys to be 1, so send/receive can work
 	// FIXME: Why doesn't crypto panic when these keys are empty?
 	keys := user.TheSession.GetKeys()
+	grp := user.TheSession.GetGroup()
 	for i := range keys {
-		keys[i].TransmissionKeys.Base = cyclic.NewInt(1)
-		keys[i].TransmissionKeys.Recursive = cyclic.NewInt(1)
+		keys[i].TransmissionKeys.Base = grp.NewInt(1)
+		keys[i].TransmissionKeys.Recursive = grp.NewInt(1)
 	}
 }
 
diff --git a/bindings/client_test.go b/bindings/client_test.go
index 58b2ccef4c90745c287e261ff8f7d9ca585e8f51..2c2433cb4692e04fa24b87060496b4513d08b57a 100644
--- a/bindings/client_test.go
+++ b/bindings/client_test.go
@@ -194,7 +194,7 @@ func TestDisableBlockingTransmission(t *testing.T) {
 func TestSetRateLimiting(t *testing.T) {
 	u, _ := user.Users.GetUser(id.NewUserFromUint(1, t))
 	nk := make([]user.NodeKeys, 1)
-	user.TheSession = user.NewSession(u, gwAddress, nk, nil)
+	user.TheSession = user.NewSession(u, gwAddress, nk, nil, nil)
 	if io.TransmitDelay != time.Duration(1000)*time.Millisecond {
 		t.Errorf("SetRateLimiting not intilized properly")
 	}
diff --git a/cmd/root.go b/cmd/root.go
index 03d09c34a50768b6602b94d00505a946130f6e41..4c2b5bda8be742a01947f73189d0bb3f320b679b 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -265,6 +265,7 @@ var rootCmd = &cobra.Command{
 		// Only send a message if we have a message to send (except dummy messages)
 		recipientId := new(id.User).SetUints(&[4]uint64{0, 0, 0, destinationUserId})
 		senderId := new(id.User).SetUints(&[4]uint64{0, 0, 0, userId})
+		grp := user.TheSession.GetGroup()
 		if message != "" {
 			// Get the recipient's nick
 			recipientNick := ""
@@ -275,7 +276,7 @@ var rootCmd = &cobra.Command{
 
 			// Handle sending to UDB
 			if *recipientId == *bots.UdbID {
-				fmt.Println(parseUdbMessage(message))
+				fmt.Println(parseUdbMessage(message, grp))
 			} else {
 				// Handle sending to any other destination
 				wireOut := bindings.FormatTextMessage(message)
diff --git a/cmd/udb.go b/cmd/udb.go
index 6fabdf6ae7258a1570bb49ba76a34130f5fecbd2..bfe0596a196f6f477c73c674d2f0a9215fa82f2b 100644
--- a/cmd/udb.go
+++ b/cmd/udb.go
@@ -15,7 +15,7 @@ import (
 )
 
 // Determines what UDB send function to call based on the text in the message
-func parseUdbMessage(msg string) string {
+func parseUdbMessage(msg string, grp *cyclic.Group) string {
 	// Split the message on spaces
 	args := strings.Fields(msg)
 	if len(args) < 3 {
@@ -31,7 +31,7 @@ func parseUdbMessage(msg string) string {
 		if err != nil {
 			return fmt.Sprintf("UDB search failed: %v", err.Error())
 		} else {
-			userIdText := cyclic.NewIntFromBytes(result.ResultID).Text(10)
+			userIdText := grp.NewIntFromBytes(result.ResultID).Text(10)
 			return fmt.Sprintf("UDB search successful. Returned user %v, "+
 				"public key %q", userIdText, result.PublicKey)
 		}
diff --git a/crypto/decrypt.go b/crypto/decrypt.go
index 7824c8f4b2f8b067b14fca9a490786726dd14792..7c403429ddb1fe91b947f6688ac85a8bf522ec90 100644
--- a/crypto/decrypt.go
+++ b/crypto/decrypt.go
@@ -22,7 +22,7 @@ func Decrypt(nodeKey *cyclic.Int, g *cyclic.Group,
 	*format.Message, error) {
 
 	// Receive and decrypt a message
-	payload := cyclic.NewIntFromBytes(cmixMsg.MessagePayload)
+	payload := g.NewIntFromBytes(cmixMsg.MessagePayload)
 
 	// perform the CMIX decryption
 	g.Mul(payload, nodeKey, payload)
diff --git a/crypto/encrypt.go b/crypto/encrypt.go
index 26b9b47add2a48c621a9e7f18bc6cfcce3c7647b..8489df89d0bd3695bf09fc309b7f51362dfffa28 100644
--- a/crypto/encrypt.go
+++ b/crypto/encrypt.go
@@ -73,8 +73,8 @@ func Encrypt(key *cyclic.Int, g *cyclic.Group,
 	message.SetRecipientMIC(mic)
 
 	// perform the CMIX encryption
-	resultPayload := cyclic.NewIntFromBytes(message.SerializePayload())
-	resultAssociatedData := cyclic.NewIntFromBytes(message.SerializeAssociatedData())
+	resultPayload := g.NewIntFromBytes(message.SerializePayload())
+	resultAssociatedData := g.NewIntFromBytes(message.SerializeAssociatedData())
 	g.Mul(resultPayload, key, resultPayload)
 	g.Mul(resultAssociatedData, key, resultAssociatedData)
 
diff --git a/crypto/encryptdecrypt_test.go b/crypto/encryptdecrypt_test.go
index 448154134fd1cd42236cdd89184cb4fb6cd000c6..9707b36fa2eede66352329c83fc425207e640358 100644
--- a/crypto/encryptdecrypt_test.go
+++ b/crypto/encryptdecrypt_test.go
@@ -10,7 +10,6 @@ import (
 	"bytes"
 	"gitlab.com/elixxir/client/user"
 	pb "gitlab.com/elixxir/comms/mixmessages"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/crypto/e2e"
 	cmix "gitlab.com/elixxir/crypto/messaging"
 	"gitlab.com/elixxir/primitives/format"
@@ -44,10 +43,8 @@ var salt = []byte(
 	"fdecfa52a8ad1688dbfa7d16df74ebf27e535903c469cefc007ebbe1ee895064")
 
 func setup(t *testing.T) {
-	rng := cyclic.NewRandom(cyclic.NewInt(0), cyclic.NewInt(1000))
-	grp := cyclic.NewGroup(cyclic.NewIntFromString(PRIME, 16),
-		cyclic.NewInt(123456789), cyclic.NewInt(8), rng)
-	Grp = &grp
+	// Init Grp var
+	InitCrypto()
 
 	u, _ := user.Users.GetUser(id.NewUserFromUint(1, t))
 
@@ -58,12 +55,12 @@ func setup(t *testing.T) {
 		// this makes it possible for the reception key to decrypt the
 		// transmission key without spinning up a whole server to decouple them
 
-		nk[i].TransmissionKeys.Base = cyclic.NewInt(1)
-		nk[i].TransmissionKeys.Recursive = cyclic.NewIntFromString(
+		nk[i].TransmissionKeys.Base = Grp.NewInt(1)
+		nk[i].TransmissionKeys.Recursive = Grp.NewIntFromString(
 			"ad333f4ccea0ccf2afcab6c1b9aa2384e561aee970046e39b7f2a78c3942a251", 16)
-		nk[i].ReceptionKeys.Base = cyclic.NewInt(1)
-		nk[i].ReceptionKeys.Recursive = grp.Inverse(
-			nk[i].TransmissionKeys.Recursive, cyclic.NewInt(1))
+		nk[i].ReceptionKeys.Base = Grp.NewInt(1)
+		nk[i].ReceptionKeys.Recursive = Grp.Inverse(
+			nk[i].TransmissionKeys.Recursive, Grp.NewInt(1))
 	}
 	user.TheSession = user.NewSession(u, "", nk, nil)
 }
@@ -81,7 +78,7 @@ func TestEncryptDecrypt(t *testing.T) {
 	msg.SetPayloadData(msgPayload)
 
 	// Generate a compound encryption key
-	encryptionKey := cyclic.NewInt(1)
+	encryptionKey := Grp.NewInt(1)
 	for _, key := range user.TheSession.GetKeys() {
 		baseKey := key.TransmissionKeys.Base
 		partialEncryptionKey := cmix.NewEncryptionKey(salt, baseKey, Grp)
@@ -89,7 +86,7 @@ func TestEncryptDecrypt(t *testing.T) {
 		//TODO: Add KMAC generation here
 	}
 
-	decryptionKey := cyclic.NewMaxInt()
+	decryptionKey := Grp.NewMaxInt()
 	Grp.Inverse(encryptionKey, decryptionKey)
 
 	// do the encryption and the decryption
diff --git a/crypto/group.go b/crypto/group.go
index bfa13e4eee7bae8b12725ed49f211ba87fa4cf7f..95eb08bd1b7820b6a9926e1d25b97745acaf3091 100644
--- a/crypto/group.go
+++ b/crypto/group.go
@@ -5,31 +5,44 @@
 ////////////////////////////////////////////////////////////////////////////////
 package crypto
 
-import "gitlab.com/elixxir/crypto/cyclic"
+import (
+	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/crypto/large"
+)
 
 // Grp is the global cyclic group used by cMix
-var Grp *cyclic.Group
+// var Grp *cyclic.Group
 
 // InitCrypto sets up the cryptographic constants for cMix
-func InitCrypto() {
-	// TODO: don't hard code the cyclic group
-	primeString := "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" +
-		"29024E088A67CC74020BBEA63B139B22514A08798E3404DD" +
-		"EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" +
-		"E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" +
-		"EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" +
-		"C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" +
-		"83655D23DCA3AD961C62F356208552BB9ED529077096966D" +
-		"670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" +
-		"E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" +
-		"DE2BCBF6955817183995497CEA956AE515D2261898FA0510" +
-		"15728E5A8AACAA68FFFFFFFFFFFFFFFF"
-
-	prime := cyclic.NewIntFromString(primeString, 16)
-	one := cyclic.NewInt(1)
-	primeMinusOne := cyclic.NewInt(0)
-	primeMinusOne.Sub(prime, one)
-	rng := cyclic.NewRandom(cyclic.NewInt(2), primeMinusOne)
-	g := cyclic.NewGroup(prime, cyclic.NewInt(5), cyclic.NewInt(4), rng)
-	Grp = &g
+func InitCrypto() *cyclic.Group{
+
+	base := 16
+
+	pString := "9DB6FB5951B66BB6FE1E140F1D2CE5502374161FD6538DF1648218642F0B5C48" +
+	"C8F7A41AADFA187324B87674FA1822B00F1ECF8136943D7C55757264E5A1A44F" +
+	"FE012E9936E00C1D3E9310B01C7D179805D3058B2A9F4BB6F9716BFE6117C6B5" +
+	"B3CC4D9BE341104AD4A80AD6C94E005F4B993E14F091EB51743BF33050C38DE2" +
+	"35567E1B34C3D6A5C0CEAA1A0F368213C3D19843D0B4B09DCB9FC72D39C8DE41" +
+	"F1BF14D4BB4563CA28371621CAD3324B6A2D392145BEBFAC748805236F5CA2FE" +
+	"92B871CD8F9C36D3292B5509CA8CAA77A2ADFC7BFD77DDA6F71125A7456FEA15" +
+	"3E433256A2261C6A06ED3693797E7995FAD5AABBCFBE3EDA2741E375404AE25B"
+
+	gString := "5C7FF6B06F8F143FE8288433493E4769C4D988ACE5BE25A0E24809670716C613" +
+		"D7B0CEE6932F8FAA7C44D2CB24523DA53FBE4F6EC3595892D1AA58C4328A06C4" +
+		"6A15662E7EAA703A1DECF8BBB2D05DBE2EB956C142A338661D10461C0D135472" +
+		"085057F3494309FFA73C611F78B32ADBB5740C361C9F35BE90997DB2014E2EF5" +
+		"AA61782F52ABEB8BD6432C4DD097BC5423B285DAFB60DC364E8161F4A2A35ACA" +
+		"3A10B1C4D203CC76A470A33AFDCBDD92959859ABD8B56E1725252D78EAC66E71" +
+		"BA9AE3F1DD2487199874393CD4D832186800654760E1E34C09E4D155179F9EC0" +
+		"DC4473F996BDCE6EED1CABED8B6F116F7AD9CF505DF0F998E34AB27514B0FFE7"
+
+	qString := "F2C3119374CE76C9356990B465374A17F23F9ED35089BD969F61C6DDE9998C1F"
+
+	p := large.NewIntFromString(pString, base)
+	g := large.NewIntFromString(gString, base)
+	q := large.NewIntFromString(qString, base)
+
+	grp := cyclic.NewGroup(p, g, q)
+
+	return &grp
 }
diff --git a/glide.yaml b/glide.yaml
index 65ab97a9a59790b290525cd6c1788f4a71b9a300..6fa353afa9ea34cf6ce0b8fffe08a94734de9657 100644
--- a/glide.yaml
+++ b/glide.yaml
@@ -4,7 +4,7 @@ import:
   version: master
   vcs: git
 - package: gitlab.com/elixxir/crypto
-  version: master
+  version: cyclic-refactor
   repo: git@gitlab.com:elixxir/crypto
   vcs: git
 - package: gitlab.com/elixxir/comms
diff --git a/io/collate_test.go b/io/collate_test.go
index 82e60794e78c50f9cec1636968e67578af70b9b5..0f196c4850dce53033e9d41b90f32b05c833805a 100644
--- a/io/collate_test.go
+++ b/io/collate_test.go
@@ -9,9 +9,9 @@ package io
 import (
 	"bytes"
 	"encoding/hex"
+	"gitlab.com/elixxir/client/crypto"
 	"gitlab.com/elixxir/client/parse"
 	"gitlab.com/elixxir/client/user"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/format"
 	"gitlab.com/elixxir/primitives/id"
 	"math/rand"
@@ -20,10 +20,10 @@ import (
 )
 
 func TestCollator_AddMessage(t *testing.T) {
-
+	grp := crypto.InitCrypto()
 	user.TheSession = user.NewSession(&user.User{id.NewUserFromUint(8, t),
 		"test"}, "",
-		[]user.NodeKeys{}, cyclic.NewInt(0))
+		[]user.NodeKeys{}, grp.NewInt(0), grp)
 
 	collator := &collator{
 		pendingMessages: make(map[PendingMessageKey]*multiPartMessage),
@@ -69,10 +69,10 @@ func TestCollator_AddMessage(t *testing.T) {
 }
 
 func TestCollator_AddMessage_Timeout(t *testing.T) {
-
+	grp := crypto.InitCrypto()
 	user.TheSession = user.NewSession(&user.User{id.NewUserFromUint(8, t),
 		"test"}, "",
-		[]user.NodeKeys{}, cyclic.NewInt(0))
+		[]user.NodeKeys{}, grp.NewInt(0), grp)
 
 	collator := &collator{
 		pendingMessages: make(map[PendingMessageKey]*multiPartMessage),
diff --git a/io/messaging.go b/io/messaging.go
index bd69ec4ebd571720ab25374c9bb680e6938665eb..f933506c4ef9a52f4ac0a4b8f4fc63431ba81619 100644
--- a/io/messaging.go
+++ b/io/messaging.go
@@ -71,6 +71,7 @@ func (m *messaging) SendMessage(recipientID *id.User,
 	// in this library? why not pass a sender object instead?
 	globals.Log.DEBUG.Printf("Sending message to %q: %q", *recipientID, message)
 	userID := user.TheSession.GetCurrentUser().User
+	grp := user.TheSession.GetGroup()
 	parts, err := parse.Partition([]byte(message),
 		m.nextId())
 	if err != nil {
@@ -100,7 +101,7 @@ func (m *messaging) SendMessage(recipientID *id.User,
 		// The timestamp will be encrypted later
 		message.SetTimestamp(nowBytes)
 		message.SetPayloadData(parts[i])
-		err = send(userID, message)
+		err = send(userID, message, grp)
 		if err != nil {
 			return fmt.Errorf("SendMessage send() error: %v", err.Error())
 		}
@@ -109,7 +110,7 @@ func (m *messaging) SendMessage(recipientID *id.User,
 }
 
 // send actually sends the message to the server
-func send(senderID *id.User, message *format.Message) error {
+func send(senderID *id.User, message *format.Message, grp *cyclic.Group) error {
 	// Enable transmission blocking if enabled
 	if BlockTransmissions {
 		sendLock.Lock()
@@ -125,19 +126,19 @@ func send(senderID *id.User, message *format.Message) error {
 	macs := make([][]byte, 0)
 
 	// Generate a compound encryption key
-	encryptionKey := cyclic.NewInt(1)
+	encryptionKey := grp.NewInt(1)
 	for _, key := range user.TheSession.GetKeys() {
 		baseKey := key.TransmissionKeys.Base
-		partialEncryptionKey := cmix.NewEncryptionKey(salt, baseKey, crypto.Grp)
-		crypto.Grp.Mul(encryptionKey, partialEncryptionKey, encryptionKey)
+		partialEncryptionKey := cmix.NewEncryptionKey(salt, baseKey, grp)
+		grp.Mul(encryptionKey, partialEncryptionKey, encryptionKey)
 		//TODO: Add KMAC generation here
 	}
 
 	// TBD: Is there a really good reason we have to specify the Grp and not a
 	// key? Should we even be doing the encryption here?
 	// TODO: Use salt here / generate n key map
-	e2eKey := e2e.Keygen(crypto.Grp, nil, nil)
-	associatedData, payload := crypto.Encrypt(encryptionKey, crypto.Grp,
+	e2eKey := e2e.Keygen(grp, nil, nil)
+	associatedData, payload := crypto.Encrypt(encryptionKey, grp,
 		message, e2eKey)
 	msgPacket := &pb.CmixMessage{
 		SenderID:       senderID.Bytes(),
@@ -210,6 +211,7 @@ func (m *messaging) receiveMessagesFromGateway(
 		}
 
 		results := make([]*format.Message, 0, len(messages.MessageIDs))
+		grp := user.TheSession.GetGroup()
 		for _, messageID := range messages.MessageIDs {
 			// Get the first unseen message from the list of IDs
 			_, received := ReceivedMessages[messageID]
@@ -238,12 +240,12 @@ func (m *messaging) receiveMessagesFromGateway(
 
 					// Generate a compound decryption key
 					salt := newMessage.Salt
-					decryptionKey := cyclic.NewInt(1)
+					decryptionKey := grp.NewInt(1)
 					for _, key := range user.TheSession.GetKeys() {
 						baseKey := key.ReceptionKeys.Base
 						partialDecryptionKey := cmix.NewDecryptionKey(salt, baseKey,
-							crypto.Grp)
-						crypto.Grp.Mul(decryptionKey, partialDecryptionKey, decryptionKey)
+							grp)
+						grp.Mul(decryptionKey, partialDecryptionKey, decryptionKey)
 						//TODO: Add KMAC verification here
 					}
 
@@ -253,7 +255,7 @@ func (m *messaging) receiveMessagesFromGateway(
 					user.TheSession.SetLastMessageID(messageID)
 					user.TheSession.StoreSession()
 
-					decryptedMsg, err2 := crypto.Decrypt(decryptionKey, crypto.Grp,
+					decryptedMsg, err2 := crypto.Decrypt(decryptionKey, grp,
 						newMessage)
 					if err2 != nil {
 						globals.Log.WARN.Printf(
diff --git a/payment/orderedStorage_test.go b/payment/orderedStorage_test.go
index dfa38fa5b0ee2f3f860b783aff5d433aaa3ca589..c30f0d6995e0e63adf6e1be1c6029cb01c0c41a1 100644
--- a/payment/orderedStorage_test.go
+++ b/payment/orderedStorage_test.go
@@ -8,10 +8,10 @@ package payment
 
 import (
 	"github.com/mitchellh/go-homedir"
+	"gitlab.com/elixxir/client/crypto"
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/crypto/coin"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
 	"math/rand"
 	"os"
@@ -24,8 +24,9 @@ func TestCreateOrderedStorage_New(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
 	userID := id.NewUserFromUint(1, t)
+	grp := crypto.InitCrypto()
 	s := user.NewSession(&user.User{userID, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	// show that the ordered list does not exist
 	key := "TestOrderedList"
@@ -70,8 +71,9 @@ func TestCreateOrderedStorage_Load(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
 	userID := id.NewUserFromUint(1, t)
+	grp := crypto.InitCrypto()
 	s := user.NewSession(&user.User{userID, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	// show that the ordered list does not exist
 	key := "TestOrderedList"
@@ -117,9 +119,10 @@ func TestOrderedCoinStorage_Value(t *testing.T) {
 
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	userID := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{userID, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	src := rand.NewSource(42)
 	rng := rand.New(src)
@@ -141,9 +144,10 @@ func TestOrderedCoinStorage_Value(t *testing.T) {
 func TestOrderedCoinStorage_Add_Empty(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	userID := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{userID, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	cs, err := coin.NewSleeve(69)
 
@@ -164,9 +168,10 @@ func TestOrderedCoinStorage_Add_Empty(t *testing.T) {
 func TestOrderedCoinStorage_Add_Multi(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	userID := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{userID, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	ocs := OrderedCoinStorage{&[]coin.Sleeve{}, 0, s}
 
@@ -209,9 +214,10 @@ func TestOrderedCoinStorage_Add_Save(t *testing.T) {
 
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	userID := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{userID, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	// show that the ordered list does not exist
 	key := "TestOrderedList"
@@ -248,9 +254,10 @@ func TestOrderedCoinStorage_Add_Save(t *testing.T) {
 func TestOrderedCoinStorage_Get(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -288,8 +295,10 @@ func TestOrderedCoinStorage_Get(t *testing.T) {
 func TestOrderedCoinStorage_Pop(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
-	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -327,9 +336,10 @@ func TestOrderedCoinStorage_Pop(t *testing.T) {
 func TestOrderedCoinStorage_Pop_Save(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -385,9 +395,10 @@ func TestOrderedCoinStorage_Pop_Save(t *testing.T) {
 func TestOrderedCoinStorage_Fund_Insufficient(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -428,9 +439,10 @@ func TestOrderedCoinStorage_Fund_Insufficient(t *testing.T) {
 func TestOrderedCoinStorage_Fund_Single_Exact(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -472,9 +484,10 @@ func TestOrderedCoinStorage_Fund_Single_Exact(t *testing.T) {
 func TestOrderedCoinStorage_Fund_Multi_Exact(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -528,9 +541,10 @@ func TestOrderedCoinStorage_Fund_Multi_Exact(t *testing.T) {
 func TestOrderedCoinStorage_Fund_Multi_Exact_Split(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -584,9 +598,10 @@ func TestOrderedCoinStorage_Fund_Multi_Exact_Split(t *testing.T) {
 func TestOrderedCoinStorage_Fund_Organization(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -625,9 +640,10 @@ func TestOrderedCoinStorage_Fund_Organization(t *testing.T) {
 func TestOrderedCoinStorage_Fund_Multi_Exact_Split_Change(t *testing.T) {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	key := "TestOrderedList"
 
@@ -689,9 +705,10 @@ func TestOrderedStorage_FileLoading(t *testing.T) {
 		t.Error(err.Error())
 	}
 	globals.InitStorage(&globals.DefaultStorage{}, storagePath+filename)
+	grp := crypto.InitCrypto()
 	uid := id.NewUserFromUint(1, t)
 	s := user.NewSession(&user.User{uid, "test"}, "", []user.NodeKeys{},
-		cyclic.NewInt(0))
+		grp.NewInt(0), grp)
 
 	// show that the ordered list does not exist
 	key := "TestOrderedList"
diff --git a/payment/transactionList_test.go b/payment/transactionList_test.go
index d95e883563a1698cd76cf522159c6eb399ecceff..e8e5a23f3db2eef2aede07a1cba81be58c99cfab 100644
--- a/payment/transactionList_test.go
+++ b/payment/transactionList_test.go
@@ -8,11 +8,11 @@ package payment
 
 import (
 	"gitlab.com/elixxir/client/cmixproto"
+	"gitlab.com/elixxir/client/crypto"
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/client/parse"
 	"gitlab.com/elixxir/client/user"
 	"gitlab.com/elixxir/crypto/coin"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
 	"math"
 	"math/rand"
@@ -21,13 +21,18 @@ import (
 	"time"
 )
 
-// Shows that CreateTransactionList creates new storage properly
-func TestCreateTransactionList_New(t *testing.T) {
+func MockNewSession(t *testing.T) user.Session {
 	globals.LocalStorage = nil
 	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
+	grp := crypto.InitCrypto()
+	return user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
 		Nick: "test"}, "",
-		[]user.NodeKeys{}, cyclic.NewInt(0))
+		[]user.NodeKeys{}, grp.NewInt(0), grp)
+}
+
+// Shows that CreateTransactionList creates new storage properly
+func TestCreateTransactionList_New(t *testing.T) {
+	s := MockNewSession(t)
 
 	// show that the ordered list does not exist
 	key := "TestTransactionList"
@@ -70,10 +75,7 @@ func TestCreateTransactionList_New(t *testing.T) {
 
 // Shows that CreateTransactionList loads old transaction List properly
 func TestCreateTransactionList_Load(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	// show that the transaction list does not exist
 	key := "TestTransactionList"
@@ -114,10 +116,7 @@ func TestCreateTransactionList_Load(t *testing.T) {
 // Shows that TransactionList.Value returns the value of the storage correctly
 func TestTransactionList_Value(t *testing.T) {
 
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	src := rand.NewSource(42)
 	rng := rand.New(src)
@@ -136,10 +135,7 @@ func TestTransactionList_Value(t *testing.T) {
 
 // Shows that TransactionList.Upsert works when the list is empty
 func TestTransactionList_Upsert_Empty(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	tMap := make(map[parse.MessageHash]*Transaction)
 
@@ -162,10 +158,7 @@ func TestTransactionList_Upsert_Empty(t *testing.T) {
 
 // Shows that TransactionList.Upsert works when the list is not empty
 func TestTransactionList_Upsert_Multi(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	t1 := Transaction{Memo: "1"}
 	t1Hash := parse.Message{
@@ -196,10 +189,7 @@ func TestTransactionList_Upsert_Multi(t *testing.T) {
 
 // Shows that TransactionList.Upsert's results are properly saved
 func TestTransactionList_Upsert_Save(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	key := "TestTransactionList"
 
@@ -239,10 +229,7 @@ func TestTransactionList_Upsert_Save(t *testing.T) {
 
 // Shows that TransactionList.Get works when the list has multiple members
 func TestTransactionList_Get(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	t1 := Transaction{Memo: "1"}
 	t1Hash := parse.Message{
@@ -284,10 +271,7 @@ func TestTransactionList_Get(t *testing.T) {
 
 // Shows that TransactionList.Pop works when the list is not empty
 func TestTransactionList_Pop(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	t1 := Transaction{Memo: "1"}
 	t1Hash := parse.Message{
@@ -329,10 +313,7 @@ func TestTransactionList_Pop(t *testing.T) {
 
 // Shows that TransactionList.Pop errors properly when the element doesn't exist
 func TestTransactionList_Pop_Invalid(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	t1 := Transaction{Memo: "1"}
 	t1Hash := parse.Message{
@@ -363,10 +344,7 @@ func TestTransactionList_Pop_Invalid(t *testing.T) {
 
 // Shows that TransactionList.Upsert works when the list is not empty
 func TestTransactionList_Pop_Save(t *testing.T) {
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 
 	key := "TestTransactionList"
 
@@ -428,10 +406,7 @@ func TestTransactionList_Pop_Save(t *testing.T) {
 
 func TestTransactionList_GetKeysByTimestampDescending(t *testing.T) {
 	// populate a transaction list with some items
-	globals.LocalStorage = nil
-	globals.InitStorage(&globals.RamStorage{}, "")
-	s := user.NewSession(&user.User{User: id.NewUserFromUint(1, t),
-		Nick: "test"}, "", []user.NodeKeys{}, cyclic.NewInt(0))
+	s := MockNewSession(t)
 	transactionMap := make(map[parse.MessageHash]*Transaction)
 	transactions := TransactionList{
 		transactionMap: &transactionMap,
diff --git a/user/session.go b/user/session.go
index a5b2d5a0c54917ecc1c39fe9432d46fe7afc930a..d5c5f9c29dfc2af066fe660a7783351e887bdb20 100644
--- a/user/session.go
+++ b/user/session.go
@@ -11,13 +11,13 @@ import (
 	"encoding/gob"
 	"errors"
 	"fmt"
+	jww "github.com/spf13/jwalterweatherman"
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
 	"math/rand"
 	"sync"
 	"time"
-	jww "github.com/spf13/jwalterweatherman"
 )
 
 // Errors
@@ -35,6 +35,7 @@ type Session interface {
 	GetKeys() []NodeKeys
 	GetPrivateKey() *cyclic.Int
 	GetPublicKey() *cyclic.Int
+	GetGroup() *cyclic.Group
 	GetLastMessageID() string
 	SetLastMessageID(id string)
 	StoreSession() error
@@ -60,15 +61,16 @@ type RatchetKey struct {
 }
 
 // Creates a new Session interface for registration
-func NewSession(u *User, GatewayAddr string, nk []NodeKeys, publicKey *cyclic.Int) Session {
+func NewSession(u *User, GatewayAddr string, nk []NodeKeys, publicKey *cyclic.Int, grp *cyclic.Group) Session {
 
 	// With an underlying Session data structure
 	return Session(&SessionObj{
 		CurrentUser:  u,
 		GWAddress:    GatewayAddr, // FIXME: don't store this here
 		Keys:         nk,
-		PrivateKey:   cyclic.NewMaxInt(),
+		PrivateKey:   grp.NewMaxInt(),
 		PublicKey:    publicKey,
+		Grp:		  grp,
 		InterfaceMap: make(map[string]interface{}),
 	})
 
@@ -138,6 +140,7 @@ type SessionObj struct {
 	Keys       []NodeKeys
 	PrivateKey *cyclic.Int
 	PublicKey  *cyclic.Int
+	Grp *cyclic.Group
 
 	// Last received message ID. Check messages after this on the gateway.
 	LastMessageID string
@@ -178,6 +181,12 @@ func (s *SessionObj) GetPublicKey() *cyclic.Int {
 	return s.PublicKey
 }
 
+func (s *SessionObj) GetGroup() *cyclic.Group {
+	s.LockStorage()
+	defer s.UnlockStorage()
+	return s.Grp
+}
+
 // Return a copy of the current user
 func (s *SessionObj) GetCurrentUser() (currentUser *User) {
 	// This is where it deadlocks
@@ -332,8 +341,9 @@ func (s *SessionObj) UnlockStorage() {
 }
 
 func clearCyclicInt(c *cyclic.Int) {
-	c.Set(cyclic.NewMaxInt())
-	c.SetInt64(0)
+	c.Reset()
+	//c.Set(cyclic.NewMaxInt())
+	//c.SetInt64(0)
 }
 
 func clearRatchetKeys(r *RatchetKey) {
diff --git a/user/session_test.go b/user/session_test.go
index 48913dc1d6a4f95169e176bd0baf56fd8081bab9..d2489ed2fbe171581be5fb65b5cf15f8991a2e23 100644
--- a/user/session_test.go
+++ b/user/session_test.go
@@ -8,8 +8,8 @@ package user
 
 import (
 	"crypto/sha256"
+	"gitlab.com/elixxir/client/crypto"
 	"gitlab.com/elixxir/client/globals"
-	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
 	"testing"
 )
@@ -29,12 +29,14 @@ func TestUserSession(t *testing.T) {
 	u.User = id.NewUserFromUint(UID, t)
 	u.Nick = "Mario"
 
+	grp := crypto.InitCrypto()
+
 	keys := make([]NodeKeys, 1)
 	keys[0] = NodeKeys{
-		TransmissionKeys: RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
-		ReceptionKeys:    RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
-		ReceiptKeys:      RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
-		ReturnKeys:       RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
+		TransmissionKeys: RatchetKey{grp.NewInt(2), grp.NewInt(2)},
+		ReceptionKeys:    RatchetKey{grp.NewInt(2), grp.NewInt(2)},
+		ReceiptKeys:      RatchetKey{grp.NewInt(2), grp.NewInt(2)},
+		ReturnKeys:       RatchetKey{grp.NewInt(2), grp.NewInt(2)},
 	}
 
 	err := globals.InitStorage(&globals.RamStorage{}, "")
@@ -44,9 +46,9 @@ func TestUserSession(t *testing.T) {
 	}
 
 	//Ask Ben if there should be a Node Address here!
-	ses := NewSession(u, "abc", keys, cyclic.NewInt(2))
+	ses := NewSession(u, "abc", keys, grp.NewInt(2), grp)
 
-	ses.(*SessionObj).PrivateKey.SetInt64(2)
+	ses.(*SessionObj).PrivateKey = grp.NewInt(2)
 	ses.SetLastMessageID("totally unique ID")
 
 	err = ses.StoreSession()
@@ -124,31 +126,31 @@ func TestUserSession(t *testing.T) {
 
 		for i := 0; i < len(TheSession.GetKeys()); i++ {
 
-			if TheSession.GetPublicKey().Cmp(cyclic.NewInt(2)) != 0 {
+			if TheSession.GetPublicKey().Cmp(grp.NewInt(2)) != 0 {
 				t.Errorf("Error: Public key not set correctly!")
-			} else if TheSession.GetKeys()[i].ReceiptKeys.Base.Cmp(cyclic.
+			} else if TheSession.GetKeys()[i].ReceiptKeys.Base.Cmp(grp.
 				NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
-			} else if TheSession.GetKeys()[i].ReceiptKeys.Recursive.Cmp(cyclic.
+			} else if TheSession.GetKeys()[i].ReceiptKeys.Recursive.Cmp(grp.
 				NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
-			} else if TheSession.GetKeys()[i].ReceptionKeys.Base.Cmp(cyclic.
+			} else if TheSession.GetKeys()[i].ReceptionKeys.Base.Cmp(grp.
 				NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
 			} else if TheSession.GetKeys()[i].ReceptionKeys.Recursive.Cmp(
-				cyclic.NewInt(2)) != 0 {
+				grp.NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
-			} else if TheSession.GetKeys()[i].ReturnKeys.Base.Cmp(cyclic.
+			} else if TheSession.GetKeys()[i].ReturnKeys.Base.Cmp(grp.
 				NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
-			} else if TheSession.GetKeys()[i].ReturnKeys.Recursive.Cmp(cyclic.
+			} else if TheSession.GetKeys()[i].ReturnKeys.Recursive.Cmp(grp.
 				NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
-			} else if TheSession.GetKeys()[i].TransmissionKeys.Base.Cmp(cyclic.
+			} else if TheSession.GetKeys()[i].TransmissionKeys.Base.Cmp(grp.
 				NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
 			} else if TheSession.GetKeys()[i].TransmissionKeys.Recursive.Cmp(
-				cyclic.NewInt(2)) != 0 {
+				grp.NewInt(2)) != 0 {
 				t.Errorf("Error: Receipt base key not set correctly!")
 			}
 
@@ -233,17 +235,19 @@ func TestGetPubKey(t *testing.T) {
 	u.User = UID
 	u.Nick = "Mario"
 
+	grp := crypto.InitCrypto()
+
 	keys := make([]NodeKeys, 1)
 	keys[0] = NodeKeys{
-		TransmissionKeys: RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
-		ReceptionKeys:    RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
-		ReceiptKeys:      RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
-		ReturnKeys:       RatchetKey{cyclic.NewInt(2), cyclic.NewInt(2)},
+		TransmissionKeys: RatchetKey{grp.NewInt(2), grp.NewInt(2)},
+		ReceptionKeys:    RatchetKey{grp.NewInt(2), grp.NewInt(2)},
+		ReceiptKeys:      RatchetKey{grp.NewInt(2), grp.NewInt(2)},
+		ReturnKeys:       RatchetKey{grp.NewInt(2), grp.NewInt(2)},
 	}
 
-	ses := NewSession(u, "abc", keys, cyclic.NewInt(2))
+	ses := NewSession(u, "abc", keys, grp.NewInt(2), grp)
 	pubKey := ses.GetPublicKey()
-	if pubKey.Cmp(cyclic.NewInt(2)) != 0 {
+	if pubKey.Cmp(grp.NewInt(2)) != 0 {
 		t.Errorf("Public key is not set correctly!")
 	}
 }
diff --git a/user/user.go b/user/user.go
index 17a58652808ec774994ea9714c945de1ac1f16b2..43982f93dfce11ff2829a40679b0d84b63f531b3 100644
--- a/user/user.go
+++ b/user/user.go
@@ -8,13 +8,14 @@ package user
 
 import (
 	"crypto/sha256"
+	"gitlab.com/elixxir/client/crypto"
 	"gitlab.com/elixxir/client/globals"
 	"gitlab.com/elixxir/crypto/cyclic"
 	"gitlab.com/elixxir/primitives/id"
 )
 
 // Globally instantiated Registry
-var Users = newRegistry()
+var Users = newRegistry(crypto.InitCrypto())
 
 const NUM_DEMO_USERS = 40
 
@@ -49,7 +50,7 @@ type UserMap struct {
 }
 
 // newRegistry creates a new Registry interface
-func newRegistry() Registry {
+func newRegistry(grp *cyclic.Group) Registry {
 	if len(DemoChannelNames) > 10 || len(DemoUserNicks) > 30 {
 		globals.Log.ERROR.Print("Not enough demo users have been hardcoded.")
 	}
@@ -70,16 +71,16 @@ func newRegistry() Registry {
 		// TODO We need a better way to generate base/recursive keys
 		h := sha256.New()
 		h.Write([]byte(string(20000 + i)))
-		k.TransmissionKeys.Base = cyclic.NewIntFromBytes(h.Sum(nil))
+		k.TransmissionKeys.Base = grp.NewIntFromBytes(h.Sum(nil))
 		h = sha256.New()
 		h.Write([]byte(string(30000 + i)))
-		k.TransmissionKeys.Recursive = cyclic.NewIntFromBytes(h.Sum(nil))
+		k.TransmissionKeys.Recursive = grp.NewIntFromBytes(h.Sum(nil))
 		h = sha256.New()
 		h.Write([]byte(string(40000 + i)))
-		k.ReceptionKeys.Base = cyclic.NewIntFromBytes(h.Sum(nil))
+		k.ReceptionKeys.Base = grp.NewIntFromBytes(h.Sum(nil))
 		h = sha256.New()
 		h.Write([]byte(string(50000 + i)))
-		k.ReceptionKeys.Recursive = cyclic.NewIntFromBytes(h.Sum(nil))
+		k.ReceptionKeys.Recursive = grp.NewIntFromBytes(h.Sum(nil))
 
 		// Add user to collection and lookup table
 		uc[*t.User] = t
diff --git a/user/user_test.go b/user/user_test.go
index 9e21a5139d91cf98c0eb6888dfe0d79d680d25fa..f06ce6ac20e509c69d7f2a39d5b0a88d9ca0e7f9 100644
--- a/user/user_test.go
+++ b/user/user_test.go
@@ -8,7 +8,7 @@ package user
 
 import (
 	"crypto/sha256"
-	"gitlab.com/elixxir/crypto/cyclic"
+	"gitlab.com/elixxir/client/crypto"
 	"gitlab.com/elixxir/primitives/id"
 	"testing"
 )
@@ -65,6 +65,9 @@ func TestUserRegistry(t *testing.T) {
 			"Actual: %v", newUsr.Nick)
 	}
 
+	// Initialize group
+	grp := crypto.InitCrypto()
+
 	// Test LookupKeys
 	keys, suc := Users.LookupKeys(id.NewUserFromUint(1, t))
 	if !suc {
@@ -72,7 +75,7 @@ func TestUserRegistry(t *testing.T) {
 	}
 	h := sha256.New()
 	h.Write([]byte(string(20001)))
-	key := cyclic.NewIntFromBytes(h.Sum(nil))
+	key := grp.NewIntFromBytes(h.Sum(nil))
 	if keys.TransmissionKeys.Base.Text(16) != key.Text(16) {
 		t.Errorf("LookupKeys returned an incorrect key. "+
 			"Expected:%v \nActual%v", key.Text(16),
@@ -80,7 +83,7 @@ func TestUserRegistry(t *testing.T) {
 	}
 	h = sha256.New()
 	h.Write([]byte(string(30001)))
-	key = cyclic.NewIntFromBytes(h.Sum(nil))
+	key = grp.NewIntFromBytes(h.Sum(nil))
 	if keys.TransmissionKeys.Recursive.Text(16) != key.Text(16) {
 		t.Errorf("LookupKeys returned an incorrect key. "+
 			"Expected:%v \nActual%v", key.Text(16),
@@ -88,7 +91,7 @@ func TestUserRegistry(t *testing.T) {
 	}
 	h = sha256.New()
 	h.Write([]byte(string(40001)))
-	key = cyclic.NewIntFromBytes(h.Sum(nil))
+	key = grp.NewIntFromBytes(h.Sum(nil))
 	if keys.ReceptionKeys.Base.Text(16) != key.Text(16) {
 		t.Errorf("LookupKeys returned an incorrect key. "+
 			"Expected:%v \nActual%v", key.Text(16),
@@ -96,7 +99,7 @@ func TestUserRegistry(t *testing.T) {
 	}
 	h = sha256.New()
 	h.Write([]byte(string(50001)))
-	key = cyclic.NewIntFromBytes(h.Sum(nil))
+	key = grp.NewIntFromBytes(h.Sum(nil))
 	if keys.ReceptionKeys.Recursive.Text(16) != key.Text(16) {
 		t.Errorf("LookupKeys returned an incorrect key. "+
 			"Expected:%v \nActual%v", key.Text(16),