func genSalt() ([]byte, error) {
	salt := make([]byte, saltLenV1)
	if _, err := io.ReadFull(rand.Reader, salt); err != nil {
		return nil, err
	}
	return salt, nil
}
genSalt generates a salt, which can be used for the deriveKey fuction.
package filestore
import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/rand"
	"encoding/binary"
	"errors"
	"io"
	"golang.org/x/crypto/scrypt"
)
type aesCipher interface {
	Encrypt(plaintext []byte) ([]byte, error)
	Decrypt(ciphertext []byte) ([]byte, error)
}
type aesGcm struct {
	cipher.AEAD
	nonce []byte
}
func newGCM(key []byte) (aesCipher, error) {
	block, err := aes.NewCipher(key)
	if err != nil {
		return nil, err
	}
	aead, err := cipher.NewGCMWithNonceSize(block, nonceLenV1)
	if err != nil {
		return nil, err
	}
	return &aesGcm{AEAD: aead, nonce: nil}, nil
}
func (c *aesGcm) Encrypt(plaintext []byte) ([]byte, error) {
	nonceSize := c.AEAD.NonceSize()
	if c.nonce == nil {
		c.nonce = make([]byte, nonceSize)
		if _, err := io.ReadFull(rand.Reader, c.nonce); err != nil {
			return nil, err
		}
	} else {
		if err := c.incrementNonce(); err != nil {
			return nil, err
		}
	}
	ciphertext := make([]byte, nonceSize+len(plaintext)+c.AEAD.Overhead())
	copy(ciphertext[:nonceSize], c.nonce)
	c.AEAD.Seal(ciphertext[:nonceSize], c.nonce, plaintext, nil)
	return ciphertext, nil
}
func (c *aesGcm) Decrypt(ciphertext []byte) ([]byte, error) {
	nonceSize := c.AEAD.NonceSize()
	if len(ciphertext) < nonceSize {
		return nil, errors.New("ciphertext too short")
	}
	if c.nonce == nil {
		c.nonce = make([]byte, nonceSize)
	}
	copy(c.nonce, ciphertext[:nonceSize])
	return c.AEAD.Open(nil, c.nonce, ciphertext[nonceSize:], nil)
}
func (c *aesGcm) incrementNonce() error {
	counter := binary.BigEndian.Uint64(c.nonce[4:])
	counter++
	binary.BigEndian.PutUint64(c.nonce[4:], counter)
	_, err := io.ReadFull(rand.Reader, c.nonce[:4])
	return err
}