Skip to content
Snippets Groups Projects
Select Git revision
  • 96dfef9c9e87c841897b6c8347e780eb59e99bdd
  • release default protected
  • 11-22-implement-kv-interface-defined-in-collectiveversionedkvgo
  • hotfix/TestHostPool_UpdateNdf_AddFilter
  • XX-4719/announcementChannels
  • xx-4717/logLevel
  • jonah/noob-channel
  • master protected
  • XX-4707/tagDiskJson
  • xx-4698/notification-retry
  • hotfix/notifylockup
  • syncNodes
  • hotfix/localCB
  • XX-4677/NewChanManagerMobile
  • XX-4689/DmSync
  • duplicatePrefix
  • XX-4601/HavenInvites
  • finalizedUICallbacks
  • XX-4673/AdminKeySync
  • debugNotifID
  • anne/test
  • v4.7.5
  • v4.7.4
  • v4.7.3
  • v4.7.2
  • v4.7.1
  • v4.6.3
  • v4.6.1
  • v4.5.0
  • v4.4.4
  • v4.3.11
  • v4.3.8
  • v4.3.7
  • v4.3.6
  • v4.3.5
  • v4.2.0
  • v4.3.0
  • v4.3.4
  • v4.3.3
  • v4.3.2
  • v4.3.1
41 results

mnemonic.go

Blame
  • user avatar
    Benjamin Wenger authored
    d4de7265
    History
    mnemonic.go 3.15 KiB
    ///////////////////////////////////////////////////////////////////////////////
    // 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/chacha"
    	"gitlab.com/xx_network/crypto/csprng"
    	xxMnemonic "gitlab.com/xx_network/crypto/mnemonic"
    	"gitlab.com/xx_network/primitives/utils"
    	"path/filepath"
    	"strings"
    )
    
    const mnemonicFile = ".recovery"
    
    // StoreSecretWithMnemonic creates a mnemonic and uses it to encrypt the secret.
    // This encrypted data saved in storage.
    func StoreSecretWithMnemonic(secret []byte, path string) (string, error) {
    	// Use fastRNG for RNG ops (AES fortuna based RNG using system RNG)
    	rng := fastRNG.NewStreamGenerator(12, 1024, csprng.NewSystemRNG).GetStream()
    
    	// Ensure path is appended by filepath separator "/"
    	if !strings.HasSuffix(path, string(filepath.Separator)) {
    		path = path + string(filepath.Separator)
    	}
    
    	// Create a mnemonic
    	mnemonic, err := xxMnemonic.GenerateMnemonic(rng, 32)
    	if err != nil {
    		return "", errors.Errorf("Failed to generate mnemonic: %v", err)
    	}
    
    	// Decode mnemonic
    	decodedMnemonic, err := xxMnemonic.DecodeMnemonic(mnemonic)
    	if err != nil {
    		return "", errors.Errorf("Failed to decode mnemonic: %v", err)
    	}
    
    	// Encrypt secret with mnemonic as key
    	ciphertext, err := chacha.Encrypt(decodedMnemonic, secret, rng)
    	if err != nil {
    		return "", errors.Errorf("Failed to encrypt secret with mnemonic: %v", err)
    	}
    
    	// Save encrypted secret to file
    	recoveryFile := path + mnemonicFile
    	err = utils.WriteFileDef(recoveryFile, ciphertext)
    	if err != nil {
    		return "", errors.Errorf("Failed to save mnemonic information to file")
    	}
    
    	return mnemonic, nil
    }
    
    // LoadSecretWithMnemonic loads the encrypted secret from storage and decrypts
    // the secret using the given mnemonic.
    func LoadSecretWithMnemonic(mnemonic, path string) (secret []byte, err error) {
    	// Ensure path is appended by filepath separator "/"
    	if !strings.HasSuffix(path, string(filepath.Separator)) {
    		path = path + string(filepath.Separator)
    	}
    
    	// Ensure that the recovery file exists
    	recoveryFile := path + mnemonicFile
    	if !utils.Exists(recoveryFile) {
    		return nil, errors.Errorf("Recovery file does not exist. " +
    			"Did you properly set up recovery or provide an incorrect filepath?")
    	}
    
    	// Read file from storage
    	data, err := utils.ReadFile(recoveryFile)
    	if err != nil {
    		return nil, errors.Errorf("Failed to load mnemonic information: %v", err)
    	}
    
    	// Decode mnemonic
    	decodedMnemonic, err := xxMnemonic.DecodeMnemonic(mnemonic)
    	if err != nil {
    		return nil, errors.Errorf("Failed to decode mnemonic: %v", err)
    	}
    
    	// Decrypt the stored secret
    	secret, err = chacha.Decrypt(decodedMnemonic, data)
    	if err != nil {
    		return nil, errors.Errorf("Failed to decrypt secret: %v", err)
    	}
    
    	return secret, nil
    }