diff --git a/key/stateVector.go b/key/stateVector.go
index a0132c8750a4ed2fcd63c088bc835f067487b23a..939b6742f4eb30008d245d59767271b58a4c2012 100644
--- a/key/stateVector.go
+++ b/key/stateVector.go
@@ -12,19 +12,24 @@ type stateVector struct {
 	ctx *context
 	key string
 
+	// Bitfield for key states
+	// If a key is clean, its bit will be 0
+	// Otherwise, it's dirty/used/not available, and its bit will be 1
 	vect []uint64
 
 	firstAvailable uint32
 	numkeys        uint32
-	numAvalible    uint32
+	numAvailable   uint32
 
 	mux sync.RWMutex
 }
 
+// Fields must be exported for json marshal to serialize them
 type stateVectorDisk struct {
-	vect           []uint64
-	firstAvailable uint32
-	numkeys        uint32
+	Vect           []uint64
+	FirstAvailable uint32
+	NumAvailable   uint32
+	Numkeys        uint32
 }
 
 func newStateVector(ctx *context, key string, numkeys uint32) *stateVector {
@@ -35,7 +40,7 @@ func newStateVector(ctx *context, key string, numkeys uint32) *stateVector {
 		vect:           make([]uint64, numBlocks),
 		key:            key,
 		firstAvailable: 0,
-		numAvalible:    numkeys,
+		numAvailable:   numkeys,
 		numkeys:        numkeys,
 	}
 
@@ -94,7 +99,7 @@ func (sv *stateVector) Use(keynum uint32) error {
 		sv.nextAvailable()
 	}
 
-	sv.numAvalible--
+	sv.numAvailable--
 
 	return sv.save()
 }
@@ -102,7 +107,7 @@ func (sv *stateVector) Use(keynum uint32) error {
 func (sv *stateVector) GetNumAvailable() uint32 {
 	sv.mux.RLock()
 	defer sv.mux.RUnlock()
-	return sv.numAvalible
+	return sv.numAvailable
 }
 
 func (sv *stateVector) Used(keynum uint32) bool {
@@ -116,14 +121,12 @@ func (sv *stateVector) used(keynum uint32) bool {
 	block := keynum / 64
 	pos := keynum % 64
 
-	sv.vect[block] &= 1 << pos
-
 	return (sv.vect[block]>>pos)&1 == 1
 }
 
 func (sv *stateVector) Next() (uint32, error) {
 	sv.mux.Lock()
-	defer sv.mux.Lock()
+	defer sv.mux.Unlock()
 
 	if sv.firstAvailable >= sv.numkeys {
 		return sv.numkeys, errors.New("No keys remaining")
@@ -132,7 +135,7 @@ func (sv *stateVector) Next() (uint32, error) {
 	next := sv.firstAvailable
 
 	sv.nextAvailable()
-	sv.numAvalible--
+	sv.numAvailable--
 
 	return next, sv.save()
 
@@ -147,11 +150,11 @@ func (sv *stateVector) GetUnusedKeyNums() []uint32 {
 	sv.mux.RLock()
 	defer sv.mux.RUnlock()
 
-	keyNums := make([]uint32, sv.numAvalible)
+	keyNums := make([]uint32, 0, sv.numAvailable)
 
 	for keyNum := sv.firstAvailable; keyNum < sv.numkeys; keyNum++ {
 		if !sv.used(keyNum) {
-			keyNums[keyNum-sv.firstAvailable] = keyNum
+			keyNums = append(keyNums, keyNum)
 		}
 	}
 
@@ -163,11 +166,11 @@ func (sv *stateVector) GetUsedKeyNums() []uint32 {
 	sv.mux.RLock()
 	defer sv.mux.RUnlock()
 
-	keyNums := make([]uint32, sv.numkeys-sv.numAvalible)
+	keyNums := make([]uint32, 0, sv.numkeys-sv.numAvailable)
 
 	for keyNum := sv.firstAvailable; keyNum < sv.numkeys; keyNum++ {
 		if sv.used(keyNum) {
-			keyNums[keyNum-sv.firstAvailable] = keyNum
+			keyNums = append(keyNums, keyNum)
 		}
 	}
 
@@ -181,23 +184,24 @@ func (sv *stateVector) nextAvailable() {
 	block := (sv.firstAvailable + 1) / 64
 	pos := (sv.firstAvailable + 1) % 64
 
-	for ; block < uint32(len(sv.vect)) && sv.vect[block]>>pos&1 == 1; pos++ {
-		if pos == 64 {
+	for ; block < uint32(len(sv.vect)) && (sv.vect[block]>>pos)&1 == 1; pos++ {
+		if pos == 63 {
 			pos = 0
 			block++
 		}
 	}
 
-	sv.firstAvailable = pos
+	sv.firstAvailable = block*64 + pos
 }
 
 //ekv functions
 func (sv *stateVector) marshal() ([]byte, error) {
 	svd := stateVectorDisk{}
 
-	svd.firstAvailable = sv.firstAvailable
-	svd.numkeys = sv.numkeys
-	svd.vect = sv.vect
+	svd.FirstAvailable = sv.firstAvailable
+	svd.Numkeys = sv.numkeys
+	svd.NumAvailable = sv.numAvailable
+	svd.Vect = sv.vect
 
 	return json.Marshal(&svd)
 }
@@ -212,9 +216,10 @@ func (sv *stateVector) unmarshal(b []byte) error {
 		return err
 	}
 
-	sv.firstAvailable = svd.firstAvailable
-	sv.numkeys = svd.numkeys
-	sv.vect = svd.vect
+	sv.firstAvailable = svd.FirstAvailable
+	sv.numkeys = svd.Numkeys
+	sv.numAvailable = svd.NumAvailable
+	sv.vect = svd.Vect
 
 	return nil
 }
diff --git a/key/stateVector_test.go b/key/stateVector_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6f069b4307aefb0bf428a1e8c43d48858cbca5e9
--- /dev/null
+++ b/key/stateVector_test.go
@@ -0,0 +1,224 @@
+package key
+
+import (
+	"fmt"
+	"gitlab.com/elixxir/client/storage"
+	"math/bits"
+	"reflect"
+	"testing"
+)
+
+// GetNumAvailable gets the number of slots left in the state vector
+func TestStateVector_GetNumAvailable(t *testing.T) {
+	const numAvailable = 23
+	sv := &stateVector{
+		numAvailable: numAvailable,
+	}
+	// At the start, NumAvailable should be the same as numKeys
+	// as none of the keys have been used
+	if sv.GetNumAvailable() != numAvailable {
+		t.Errorf("expected %v available, actually %v available", numAvailable, sv.GetNumAvailable())
+	}
+}
+
+func TestStateVector_GetNumKeys(t *testing.T) {
+	ctx := context{
+		kv: storage.InitMem(t),
+	}
+	const numKeys = 32
+	sv := newStateVector(&ctx, "key", numKeys)
+
+	// GetNumKeys should always be the same as numKeys
+	if sv.GetNumKeys() != numKeys {
+		t.Errorf("expected %v available, actually %v available", numKeys, sv.GetNumAvailable())
+	}
+}
+
+// Shows that Next mutates vector state as expected
+// Shows that Next can find key indexes all throughout the bitfield
+func TestStateVector_Next(t *testing.T) {
+	// Expected results: all keynums, and beyond the last key
+	expectedFirstAvail := []uint32{139, 145, 300, 360, 420, 761, 868, 875, 893, 995}
+
+	ctx := context{
+		kv: storage.InitMem(t),
+	}
+	const numKeys = 1000
+	sv := newStateVector(&ctx, "key", numKeys)
+
+	// Set all bits to dirty to start
+	for i := range sv.vect {
+		sv.vect[i] = 0xffffffffffffffff
+	}
+
+	// Set a few clean bits randomly
+	const numBitsSet = 10
+	for i := 0; i < numBitsSet; i++ {
+		keyNum := expectedFirstAvail[i]
+		// Set a bit clean in the state vector
+		vectIndex := keyNum / 64
+		bitIndex := keyNum % 64
+		sv.vect[vectIndex] &= ^bits.RotateLeft64(uint64(1), int(bitIndex))
+	}
+
+	sv.numAvailable = numBitsSet
+	sv.nextAvailable()
+
+	// Calling Next ten times should give all of the keyNums we set
+	// It should change firstAvailable, but doesn't mutate the bit field itself
+	//  (that should be done with Use)
+	for numCalls := 0; numCalls < numBitsSet; numCalls++ {
+		keyNum, err := sv.Next()
+		if err != nil {
+			t.Fatal(err)
+		}
+		if keyNum != expectedFirstAvail[numCalls] {
+			t.Errorf("keynum %v didn't match expected %v at index %v", keyNum, expectedFirstAvail[numCalls], numCalls)
+		}
+	}
+
+	// One more call should cause an error
+	_, err := sv.Next()
+	if err == nil {
+		t.Error("Calling Next() after all keys have been found should result in error, as firstAvailable is more than numKeys")
+	}
+	// firstAvailable should now be beyond the end of the bitfield
+	if sv.firstAvailable < numKeys {
+		t.Error("Last Next() call should have set firstAvailable beyond numKeys")
+	}
+}
+
+// Shows that Use() mutates the state vector itself
+func TestStateVector_Use(t *testing.T) {
+	// These keyNums will be set to dirty with Use
+	keyNums := []uint32{139, 145, 300, 360, 420, 761, 868, 875, 893, 995}
+
+	ctx := context{
+		kv: storage.InitMem(t),
+	}
+	const numKeys = 1000
+	sv := newStateVector(&ctx, "key", numKeys)
+
+	// Expected vector states as bits are set
+	var expectedVect [][]uint64
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0, 0, 0, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0x200000000000000, 0, 0, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0x200000000000000, 0, 0x1000000000, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0x200000000000000, 0, 0x81000000000, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0x200000000000000, 0, 0x2000081000000000, 0, 0})
+	expectedVect = append(expectedVect, []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0x200000000000000, 0, 0x2000081000000000, 0, 0x800000000})
+
+	for numCalls := range keyNums {
+		// These calls to Use won't set nextAvailable, because the first keyNum set
+		err := sv.Use(keyNums[numCalls])
+		if err != nil {
+			t.Fatal(err)
+		}
+		if !reflect.DeepEqual(expectedVect[numCalls], sv.vect) {
+			t.Errorf("sv.vect differed from expected at index %v", numCalls)
+			fmt.Println(sv.vect)
+		}
+	}
+}
+
+func TestStateVector_Used(t *testing.T) {
+	// These keyNums should be used
+	keyNums := []uint32{139, 145, 300, 360, 420, 761, 868, 875, 893, 995}
+
+	ctx := context{
+		kv: storage.InitMem(t),
+	}
+	const numKeys = 1000
+	sv := newStateVector(&ctx, "key", numKeys)
+	sv.vect = []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0x200000000000000, 0, 0x2000081000000000, 0, 0x800000000}
+
+	for i := uint32(0); i < numKeys; i++ {
+		// if i is in keyNums, Used should be true
+		// otherwise, it should be false
+		found := false
+		for j := range keyNums {
+			if i == keyNums[j] {
+				found = true
+				break
+			}
+		}
+		if sv.Used(i) != found {
+			t.Errorf("at keynum %v Used should have been %v but was %v", i, found, sv.Used(i))
+		}
+	}
+}
+
+// Shows that the GetUsedKeyNums method returns the correct keynums
+func TestStateVector_GetUsedKeyNums(t *testing.T) {
+	// These keyNums should be used
+	keyNums := []uint32{139, 145, 300, 360, 420, 761, 868, 875, 893, 995}
+
+	ctx := context{
+		kv: storage.InitMem(t),
+	}
+	const numKeys = 1000
+	sv := newStateVector(&ctx, "key", numKeys)
+	sv.vect = []uint64{0, 0, 0x20800, 0, 0x100000000000, 0x10000000000, 0x1000000000, 0, 0, 0, 0, 0x200000000000000, 0, 0x2000081000000000, 0, 0x800000000}
+	sv.numAvailable = uint32(numKeys - len(keyNums))
+
+	usedKeyNums := sv.GetUsedKeyNums()
+	for i := range keyNums {
+		if usedKeyNums[i] != keyNums[i] {
+			t.Errorf("used keynums at %v: expected %v, got %v", i, keyNums[i], usedKeyNums[i])
+		}
+	}
+}
+
+// Shows that GetUnusedKeyNums gets all clean keynums
+func TestStateVector_GetUnusedKeyNums(t *testing.T) {
+	// These keyNums should not be used
+	keyNums := []uint32{139, 145, 300, 360, 420, 761, 868, 875, 893, 995}
+
+	ctx := context{
+		kv: storage.InitMem(t),
+	}
+	const numKeys = 1000
+	sv := newStateVector(&ctx, "key", numKeys)
+	sv.vect = []uint64{0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffdf7ff, 0xffffffffffffffff, 0xffffefffffffffff, 0xfffffeffffffffff, 0xffffffefffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfdffffffffffffff, 0xffffffffffffffff, 0xdffff7efffffffff, 0xffffffffffffffff, 0xfffffff7ffffffff}
+	sv.numAvailable = uint32(len(keyNums))
+	sv.firstAvailable = keyNums[0]
+
+	unusedKeyNums := sv.GetUnusedKeyNums()
+	for i := range keyNums {
+		if unusedKeyNums[i] != keyNums[i] {
+			t.Errorf("unused keynums at %v: expected %v, got %v", i, keyNums[i], unusedKeyNums[i])
+		}
+	}
+	if len(keyNums) != len(unusedKeyNums) {
+		t.Error("array lengths differed, so arrays must be different")
+	}
+}
+
+// Serializing and deserializing should result in the same state vector
+func TestLoadStateVector(t *testing.T) {
+	keyNums := []uint32{139, 145, 300, 360, 420, 761, 868, 875, 893, 995}
+	const numKeys = 1000
+	ctx := context{
+		kv: storage.InitMem(t),
+	}
+	sv := newStateVector(&ctx, "key", numKeys)
+	sv.vect = []uint64{0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffdf7ff, 0xffffffffffffffff, 0xffffefffffffffff, 0xfffffeffffffffff, 0xffffffefffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xfdffffffffffffff, 0xffffffffffffffff, 0xdffff7efffffffff, 0xffffffffffffffff, 0xfffffff7ffffffff}
+	sv.numAvailable = uint32(len(keyNums))
+	sv.firstAvailable = keyNums[0]
+
+	err := sv.save()
+	if err != nil {
+		t.Fatal(err)
+	}
+	sv2, err := loadStateVector(&ctx, "key")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if !reflect.DeepEqual(sv.vect, sv2.vect) {
+		t.Error("state vectors different after deserialization")
+	}
+}