diff --git a/api/mnemonic.go b/api/mnemonic.go
new file mode 100644
index 0000000000000000000000000000000000000000..ac4d7199a9d8eefeca533cb239d156b4307968d4
--- /dev/null
+++ b/api/mnemonic.go
@@ -0,0 +1,113 @@
+///////////////////////////////////////////////////////////////////////////////
+// Copyright © 2020 xx network SEZC                                          //
+//                                                                           //
+// Use of this source code is governed by a license that can be found in the //
+// LICENSE file                                                              //
+///////////////////////////////////////////////////////////////////////////////
+
+package api
+
+import (
+	"github.com/pkg/errors"
+	"gitlab.com/elixxir/crypto/fastRNG"
+	"gitlab.com/xx_network/crypto/csprng"
+	xxMnemonic "gitlab.com/xx_network/crypto/mnemonic"
+	"golang.org/x/crypto/salsa20"
+)
+
+const (
+	nonceSize = 8
+)
+
+// StoreSecretWithMnemonic creates a mnemonic and uses it to encrypt the secret.
+// This encrypted data saved in storage.
+func (c *Client) StoreSecretWithMnemonic(secret []byte) (string, error) {
+	rng := c.rng.GetStream()
+
+	// Create a mnemonic
+	mnemonic, err := xxMnemonic.GenerateMnemonic(rng, 32)
+	if err != nil {
+		return "", errors.Errorf("Failed to generate mnemonic: %v", err)
+	}
+
+	// Encrypt secret with mnemonic as key
+	ciphertext, nonce, err := encryptWithMnemonic(mnemonic, secret, rng)
+	if err != nil {
+		return "", errors.Errorf("Failed to encrypt secret with mnemonic: %v", err)
+	}
+
+	// Concatenate ciphertext with nonce for storage
+	data := marshalMnemonicInformation(nonce, ciphertext)
+
+	// Save data to storage
+	err = c.storage.SaveMnemonicInformation(data)
+	if err != nil {
+		return "", errors.Errorf("Failed to store mnemonic information: %v", err)
+	}
+
+	return mnemonic, nil
+}
+
+// LoadSecretWithMnemonic loads the encrypted secret from storage and decrypts
+// the secret using the given mnemonic.
+func (c *Client) LoadSecretWithMnemonic(mnemonic string) (secret []byte, err error) {
+	data, err := c.storage.LoadMnemonicInformation()
+	if err != nil {
+		return nil, errors.Errorf("Failed to load mnemonic information: %v", err)
+	}
+
+	nonce, ciphertext := unmarshalMnemonicInformation(data)
+
+	secret = decryptWithMnemonic(nonce, ciphertext, mnemonic)
+
+	return secret, nil
+}
+
+// encryptWithMnemonic is a helper function which encrypts the given secret
+// using the mnemonic as the key.
+func encryptWithMnemonic(mnemonic string, secret []byte,
+	rng *fastRNG.Stream) (ciphertext, nonce []byte, err error) {
+
+	// Place the key into a 32 byte array for salsa 20
+	var keyArray [32]byte
+	copy(keyArray[:], mnemonic)
+
+	// Generate the nonce
+	nonce, err = csprng.Generate(nonceSize, rng)
+	if err != nil {
+		return nil, nil, errors.Errorf("Failed to generate nonce for encryption: %v", err)
+	}
+
+	// Encrypt the secret
+	ciphertext = make([]byte, len(secret))
+	salsa20.XORKeyStream(ciphertext, secret, nonce, &keyArray)
+
+	return ciphertext, nonce, nil
+}
+
+// decryptWithMnemonic is a helper function which decrypts the secret
+// from storage, using the mnemonic as the key.
+func decryptWithMnemonic(nonce, ciphertext []byte, mnemonic string) (secret []byte) {
+	// Place the key into a 32 byte array for salsa 20
+	var keyArray [32]byte
+	copy(keyArray[:], mnemonic)
+
+	// Decrypt the secret
+	secret = make([]byte, len(ciphertext))
+	salsa20.XORKeyStream(secret, ciphertext, nonce, &keyArray)
+
+	return secret
+}
+
+// marshalMnemonicInformation is a helper function which concatenates the nonce
+// and ciphertext.
+func marshalMnemonicInformation(nonce, ciphertext []byte) []byte {
+	return append(nonce, ciphertext...)
+}
+
+// unmarshalMnemonicInformation is a helper function which separates the
+// concatenated data containing the nonce and ciphertext of the mnemonic
+// handling. This is the inverse of marshalMnemonicInformation.
+func unmarshalMnemonicInformation(data []byte) (nonce, ciphertext []byte) {
+	return data[:nonceSize], data[nonceSize:]
+}
diff --git a/go.mod b/go.mod
index 4374a2dd5a339fa386637cf5b8a10d5fcc367968..6d04f1cbadb4e8ba8832578bddfcce1a7c2a0075 100644
--- a/go.mod
+++ b/go.mod
@@ -22,7 +22,7 @@ require (
 	gitlab.com/elixxir/ekv v0.1.5
 	gitlab.com/elixxir/primitives v0.0.3-0.20210803231939-7b924f78eaac
 	gitlab.com/xx_network/comms v0.0.4-0.20210813170223-ab758f0bbec5
-	gitlab.com/xx_network/crypto v0.0.5-0.20210803231814-b18476a2257c
+	gitlab.com/xx_network/crypto v0.0.5-0.20210909170042-07755821e8c5
 	gitlab.com/xx_network/primitives v0.0.4-0.20210803222745-e898d5e546e9
 	golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
 	golang.org/x/net v0.0.0-20210525063256-abc453219eb5
diff --git a/go.sum b/go.sum
index c8eb24d11ebf4db213445d279faf780c546faa42..b1bcece1eb14a05bbd817eae2da9f70e9e363271 100644
--- a/go.sum
+++ b/go.sum
@@ -239,6 +239,8 @@ github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0
 github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w=
 github.com/ttacon/libphonenumber v1.2.1 h1:fzOfY5zUADkCkbIafAed11gL1sW+bJ26p6zWLBMElR4=
 github.com/ttacon/libphonenumber v1.2.1/go.mod h1:E0TpmdVMq5dyVlQ7oenAkhsLu86OkUl+yR4OAxyEg/M=
+github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8=
+github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U=
 github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 github.com/zeebo/assert v0.0.0-20181109011804-10f827ce2ed6/go.mod h1:yssERNPivllc1yU3BvpjYI5BUW+zglcz6QWqeVRL5t0=
 github.com/zeebo/assert v1.1.0 h1:hU1L1vLTHsnO8x8c9KAR5GmM5QscxHg5RNU5z5qbUWY=
@@ -272,6 +274,8 @@ gitlab.com/xx_network/crypto v0.0.3/go.mod h1:DF2HYvvCw9wkBybXcXAgQMzX+MiGbFPjwt
 gitlab.com/xx_network/crypto v0.0.4/go.mod h1:+lcQEy+Th4eswFgQDwT0EXKp4AXrlubxalwQFH5O0Mk=
 gitlab.com/xx_network/crypto v0.0.5-0.20210803231814-b18476a2257c h1:pwP50UFdh68KPcP7VopsH34/d6rIuVDwXymgFXnCOjA=
 gitlab.com/xx_network/crypto v0.0.5-0.20210803231814-b18476a2257c/go.mod h1:e/5MGrKDQbCNJnskBeDscrolr2EK5iIatEgTQnEWmOg=
+gitlab.com/xx_network/crypto v0.0.5-0.20210909170042-07755821e8c5 h1:1K+FuxnlOTHI5H2OmoBokh/K9Pbmel8VBaCdP5RW9FU=
+gitlab.com/xx_network/crypto v0.0.5-0.20210909170042-07755821e8c5/go.mod h1:hLNL8YCSiEMof0wgZHuRmN5C98TYZiLaz/rLqUYTdII=
 gitlab.com/xx_network/primitives v0.0.0-20200803231956-9b192c57ea7c/go.mod h1:wtdCMr7DPePz9qwctNoAUzZtbOSHSedcK++3Df3psjA=
 gitlab.com/xx_network/primitives v0.0.0-20200804183002-f99f7a7284da/go.mod h1:OK9xevzWCaPO7b1wiluVJGk7R5ZsuC7pHY5hteZFQug=
 gitlab.com/xx_network/primitives v0.0.2/go.mod h1:cs0QlFpdMDI6lAo61lDRH2JZz+3aVkHy+QogOB6F/qc=
diff --git a/storage/mnemonic.go b/storage/mnemonic.go
new file mode 100644
index 0000000000000000000000000000000000000000..ee9d955caaf883eade5adc6cc086c9b10517d498
--- /dev/null
+++ b/storage/mnemonic.go
@@ -0,0 +1,37 @@
+package storage
+
+import (
+	"gitlab.com/elixxir/client/storage/versioned"
+	"gitlab.com/xx_network/primitives/netTime"
+)
+
+const (
+	mnemonicKvKey     = "mnemonic"
+	mnemonicKvVersion = 0
+	mnemonicPath      = "/.recovery"
+)
+
+func (s *Session) SaveMnemonicInformation(data []byte) error {
+	s.mnemonicMux.Lock()
+	defer s.mnemonicMux.Unlock()
+
+	vo := &versioned.Object{
+		Version:   mnemonicKvVersion,
+		Timestamp: netTime.Now(),
+		Data:      data,
+	}
+
+	return s.mnemonicKV.Set(mnemonicKvKey, mnemonicKvVersion, vo)
+}
+
+func (s *Session) LoadMnemonicInformation() ([]byte, error) {
+	s.mux.RLock()
+	defer s.mux.RUnlock()
+
+	vo, err := s.mnemonicKv.Get(mnemonicKvKey, mnemonicKvVersion)
+	if err != nil {
+		return nil, err
+	}
+
+	return vo.Data, err
+}
diff --git a/storage/session.go b/storage/session.go
index e42cad445594e30d7b85eafa688d90b80d4d62ed..aadf9ffb849726ff1d775a37c101d52a3143b274 100644
--- a/storage/session.go
+++ b/storage/session.go
@@ -46,8 +46,12 @@ const currentSessionVersion = 0
 
 // Session object, backed by encrypted filestore
 type Session struct {
-	kv  *versioned.KV
-	mux sync.RWMutex
+	kv         *versioned.KV
+	mnemonicKV *versioned.KV
+	mnemonicKv *versioned.KV
+
+	mux         sync.RWMutex
+	mnemonicMux sync.RWMutex
 
 	//memoized data
 	regStatus RegistrationStatus
@@ -78,8 +82,16 @@ func initStore(baseDir, password string) (*Session, error) {
 			"Failed to create storage session")
 	}
 
+	// Create a separate file store system for account recovery
+	mnemonicFS, err := ekv.NewFilestore(baseDir+mnemonicPath, password)
+	if err != nil {
+		return nil, errors.WithMessage(err,
+			"Failed to create mnemonic store")
+	}
+
 	s = &Session{
-		kv: versioned.NewKV(fs),
+		kv:         versioned.NewKV(fs),
+		mnemonicKV: versioned.NewKV(mnemonicFS),
 	}
 
 	return s, nil