github.com/emmansun/gmsm@v0.29.1/pkcs/kdf_scrypt.go (about)

     1  package pkcs
     2  
     3  //
     4  // Reference https://datatracker.ietf.org/doc/html/rfc7914
     5  //
     6  
     7  import (
     8  	"encoding/asn1"
     9  
    10  	"golang.org/x/crypto/scrypt"
    11  )
    12  
    13  var (
    14  	oidScrypt = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 11591, 4, 11}
    15  )
    16  
    17  func init() {
    18  	RegisterKDF(oidScrypt, func() KDFParameters {
    19  		return new(scryptParams)
    20  	})
    21  }
    22  
    23  type scryptParams struct {
    24  	Salt                     []byte
    25  	CostParameter            int
    26  	BlockSize                int
    27  	ParallelizationParameter int
    28  	KeyLen                   int `asn1:"optional"`
    29  }
    30  
    31  func (p scryptParams) DeriveKey(oidKDF asn1.ObjectIdentifier, password []byte, size int) (key []byte, err error) {
    32  	return scrypt.Key(password, p.Salt, p.CostParameter, p.BlockSize,
    33  		p.ParallelizationParameter, size)
    34  }
    35  
    36  func (p scryptParams) KeyLength() int {
    37  	return p.KeyLen
    38  }
    39  
    40  // ScryptOpts contains options for the scrypt key derivation function.
    41  type ScryptOpts struct {
    42  	SaltSize                 int
    43  	CostParameter            int
    44  	BlockSize                int
    45  	ParallelizationParameter int
    46  }
    47  
    48  // NewScryptOpts returns a new ScryptOpts with the specified parameters.
    49  func NewScryptOpts(saltSize, costParameter, blockSize, parallelizationParameter int) ScryptOpts {
    50  	return ScryptOpts{
    51  		SaltSize:                 saltSize,
    52  		CostParameter:            costParameter,
    53  		BlockSize:                blockSize,
    54  		ParallelizationParameter: parallelizationParameter,
    55  	}
    56  }
    57  
    58  func (p ScryptOpts) DeriveKey(password, salt []byte, size int) (
    59  	key []byte, params KDFParameters, err error) {
    60  
    61  	key, err = scrypt.Key(password, salt, p.CostParameter, p.BlockSize,
    62  		p.ParallelizationParameter, size)
    63  	if err != nil {
    64  		return nil, nil, err
    65  	}
    66  	params = scryptParams{
    67  		BlockSize:                p.BlockSize,
    68  		CostParameter:            p.CostParameter,
    69  		ParallelizationParameter: p.ParallelizationParameter,
    70  		Salt:                     salt,
    71  		KeyLen:                   size,
    72  	}
    73  	return key, params, nil
    74  }
    75  
    76  func (p ScryptOpts) GetSaltSize() int {
    77  	return p.SaltSize
    78  }
    79  
    80  func (p ScryptOpts) OID() asn1.ObjectIdentifier {
    81  	return oidScrypt
    82  }