git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/crypto/kdf.go (about)

     1  package crypto
     2  
     3  import (
     4  	"errors"
     5  
     6  	"golang.org/x/crypto/argon2"
     7  	"golang.org/x/crypto/blake2b"
     8  )
     9  
    10  const (
    11  	// KeySize128 is the size in bytes of a 128 bits key
    12  	KeySize128 = 32
    13  	// KeySize256 is the size in bytes of a 256 bits key
    14  	KeySize256 = 32
    15  	// KeySize384 is the size in bytes of a 384 bits key
    16  	KeySize384 = 48
    17  	// KeySize512 is the size in bytes of a 512 bits key
    18  	KeySize512 = 64
    19  	// KeySize1024 is the size in bytes of a 1024 bits key
    20  	KeySize1024 = 128
    21  	// KeySize2048 is the size in bytes of a 2048 bits key
    22  	KeySize2048 = 256
    23  	// KeySize4096 is the size in bytes of a 4096 bits key
    24  	KeySize4096 = 512
    25  )
    26  
    27  // DeriveKeyFromPasswordParams describes the input parameters used by the Argon2id algorithm.
    28  type DeriveKeyFromPasswordParams struct {
    29  	// The amount of memory used by the algorithm (in kibibytes).
    30  	Memory uint32
    31  
    32  	// The number of iterations over the memory.
    33  	Iterations uint32
    34  
    35  	// The number of threads (or lanes) used by the algorithm.
    36  	Parallelism uint8
    37  
    38  	// Size of the generated key. 32 bytes or more is recommended.
    39  	KeySize uint32
    40  }
    41  
    42  // DefaultDeriveKeyFromPasswordParams provides some sane default parameters for deriving keys passwords.
    43  // You are encouraged to change the Memory, Iterations and Parallelism parameters
    44  // to values appropriate for the environment that your code will be running in.
    45  var DefaultDeriveKeyFromPasswordParams = DeriveKeyFromPasswordParams{
    46  	Memory:      64 * 1024,
    47  	Iterations:  5,
    48  	Parallelism: 2,
    49  	KeySize:     KeySize256,
    50  }
    51  
    52  // DeriveKeyFromPassword derives a key from a human provided password using the argon2id Key Derivation
    53  // Function
    54  func DeriveKeyFromPassword(password, salt []byte, params DeriveKeyFromPasswordParams) ([]byte, error) {
    55  	key := argon2.IDKey(password, salt, params.Iterations, params.Memory, params.Parallelism, params.KeySize)
    56  	if key == nil {
    57  		return nil, errors.New("crypto: Deriving key from password")
    58  	}
    59  	return key, nil
    60  }
    61  
    62  // DeriveKeyFromKey derives a key from a high entropy key using the blake2b function
    63  func DeriveKeyFromKey(key, info []byte, keySize uint8) ([]byte, error) {
    64  	if keySize < 1 || keySize > 64 {
    65  		return nil, errors.New("crypto: keySize must be between 1 and 64")
    66  	}
    67  
    68  	blake2bHash, err := blake2b.New(int(keySize), key)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  
    73  	blake2bHash.Write(info)
    74  	return blake2bHash.Sum(nil), nil
    75  }