github.com/mit-dci/lit@v0.0.0-20221102210550-8c3d3b49f2ce/btcutil/hdkeychain/extendedkey.go (about)

     1  // Copyright (c) 2014-2016 The btcsuite developers
     2  // Use of this source code is governed by an ISC
     3  // license that can be found in the LICENSE file.
     4  
     5  package hdkeychain
     6  
     7  // References:
     8  //   [BIP32]: BIP0032 - Hierarchical Deterministic Wallets
     9  //   https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki
    10  
    11  import (
    12  	"bytes"
    13  	"crypto/hmac"
    14  	"crypto/rand"
    15  	"crypto/sha512"
    16  	"encoding/binary"
    17  	"errors"
    18  	"fmt"
    19  	"github.com/mit-dci/lit/btcutil"
    20  	"github.com/mit-dci/lit/btcutil/base58"
    21  	"github.com/mit-dci/lit/btcutil/chaincfg/chainhash"
    22  	"github.com/mit-dci/lit/coinparam"
    23  	"github.com/mit-dci/lit/crypto/koblitz"
    24  	"math/big"
    25  )
    26  
    27  const (
    28  	// RecommendedSeedLen is the recommended length in bytes for a seed
    29  	// to a master node.
    30  	RecommendedSeedLen = 32 // 256 bits
    31  
    32  	// HardenedKeyStart is the index at which a hardended key starts.  Each
    33  	// extended key has 2^31 normal child keys and 2^31 hardned child keys.
    34  	// Thus the range for normal child keys is [0, 2^31 - 1] and the range
    35  	// for hardened child keys is [2^31, 2^32 - 1].
    36  	HardenedKeyStart = 0x80000000 // 2^31
    37  
    38  	// MinSeedBytes is the minimum number of bytes allowed for a seed to
    39  	// a master node.
    40  	MinSeedBytes = 16 // 128 bits
    41  
    42  	// MaxSeedBytes is the maximum number of bytes allowed for a seed to
    43  	// a master node.
    44  	MaxSeedBytes = 64 // 512 bits
    45  
    46  	// serializedKeyLen is the length of a serialized public or private
    47  	// extended key.  It consists of 4 bytes version, 1 byte depth, 4 bytes
    48  	// fingerprint, 4 bytes child number, 32 bytes chain code, and 33 bytes
    49  	// public/private key data.
    50  	serializedKeyLen = 4 + 1 + 4 + 4 + 32 + 33 // 78 bytes
    51  )
    52  
    53  var (
    54  	// ErrDeriveHardFromPublic describes an error in which the caller
    55  	// attempted to derive a hardened extended key from a public key.
    56  	ErrDeriveHardFromPublic = errors.New("cannot derive a hardened key " +
    57  		"from a public key")
    58  
    59  	// ErrNotPrivExtKey describes an error in which the caller attempted
    60  	// to extract a private key from a public extended key.
    61  	ErrNotPrivExtKey = errors.New("unable to create private keys from a " +
    62  		"public extended key")
    63  
    64  	// ErrInvalidChild describes an error in which the child at a specific
    65  	// index is invalid due to the derived key falling outside of the valid
    66  	// range for secp256k1 private keys.  This error indicates the caller
    67  	// should simply ignore the invalid child extended key at this index and
    68  	// increment to the next index.
    69  	ErrInvalidChild = errors.New("the extended key at this index is invalid")
    70  
    71  	// ErrUnusableSeed describes an error in which the provided seed is not
    72  	// usable due to the derived key falling outside of the valid range for
    73  	// secp256k1 private keys.  This error indicates the caller must choose
    74  	// another seed.
    75  	ErrUnusableSeed = errors.New("unusable seed")
    76  
    77  	// ErrInvalidSeedLen describes an error in which the provided seed or
    78  	// seed length is not in the allowed range.
    79  	ErrInvalidSeedLen = fmt.Errorf("seed length must be between %d and %d "+
    80  		"bits", MinSeedBytes*8, MaxSeedBytes*8)
    81  
    82  	// ErrBadChecksum describes an error in which the checksum encoded with
    83  	// a serialized extended key does not match the calculated value.
    84  	ErrBadChecksum = errors.New("bad extended key checksum")
    85  
    86  	// ErrInvalidKeyLen describes an error in which the provided serialized
    87  	// key is not the expected length.
    88  	ErrInvalidKeyLen = errors.New("the provided serialized extended key " +
    89  		"length is invalid")
    90  )
    91  
    92  // masterKey is the master key used along with a random seed used to generate
    93  // the master node in the hierarchical tree.
    94  var masterKey = []byte("Bitcoin seed")
    95  
    96  // ExtendedKey houses all the information needed to support a hierarchical
    97  // deterministic extended key.  See the package overview documentation for
    98  // more details on how to use extended keys.
    99  type ExtendedKey struct {
   100  	key       []byte // This will be the pubkey for extended pub keys
   101  	pubKey    []byte // This will only be set for extended priv keys
   102  	chainCode []byte
   103  	depth     uint16
   104  	parentFP  []byte
   105  	childNum  uint32
   106  	version   []byte
   107  	isPrivate bool
   108  }
   109  
   110  // newExtendedKey returns a new instance of an extended key with the given
   111  // fields.  No error checking is performed here as it's only intended to be a
   112  // convenience method used to create a populated struct.
   113  func newExtendedKey(version, key, chainCode, parentFP []byte, depth uint16,
   114  	childNum uint32, isPrivate bool) *ExtendedKey {
   115  
   116  	// NOTE: The pubKey field is intentionally left nil so it is only
   117  	// computed and memoized as required.
   118  	return &ExtendedKey{
   119  		key:       key,
   120  		chainCode: chainCode,
   121  		depth:     depth,
   122  		parentFP:  parentFP,
   123  		childNum:  childNum,
   124  		version:   version,
   125  		isPrivate: isPrivate,
   126  	}
   127  }
   128  
   129  // pubKeyBytes returns bytes for the serialized compressed public key associated
   130  // with this extended key in an efficient manner including memoization as
   131  // necessary.
   132  //
   133  // When the extended key is already a public key, the key is simply returned as
   134  // is since it's already in the correct form.  However, when the extended key is
   135  // a private key, the public key will be calculated and memoized so future
   136  // accesses can simply return the cached result.
   137  func (k *ExtendedKey) pubKeyBytes() []byte {
   138  	// Just return the key if it's already an extended public key.
   139  	if !k.isPrivate {
   140  		return k.key
   141  	}
   142  
   143  	// This is a private extended key, so calculate and memoize the public
   144  	// key if needed.
   145  	if len(k.pubKey) == 0 {
   146  		pkx, pky := koblitz.S256().ScalarBaseMult(k.key)
   147  		pubKey := koblitz.PublicKey{Curve: koblitz.S256(), X: pkx, Y: pky}
   148  		k.pubKey = pubKey.SerializeCompressed()
   149  	}
   150  
   151  	return k.pubKey
   152  }
   153  
   154  // IsPrivate returns whether or not the extended key is a private extended key.
   155  //
   156  // A private extended key can be used to derive both hardened and non-hardened
   157  // child private and public extended keys.  A public extended key can only be
   158  // used to derive non-hardened child public extended keys.
   159  func (k *ExtendedKey) IsPrivate() bool {
   160  	return k.isPrivate
   161  }
   162  
   163  // ParentFingerprint returns a fingerprint of the parent extended key from which
   164  // this one was derived.
   165  func (k *ExtendedKey) ParentFingerprint() uint32 {
   166  	return binary.BigEndian.Uint32(k.parentFP)
   167  }
   168  
   169  // Child returns a derived child extended key at the given index.  When this
   170  // extended key is a private extended key (as determined by the IsPrivate
   171  // function), a private extended key will be derived.  Otherwise, the derived
   172  // extended key will be also be a public extended key.
   173  //
   174  // When the index is greater to or equal than the HardenedKeyStart constant, the
   175  // derived extended key will be a hardened extended key.  It is only possible to
   176  // derive a hardended extended key from a private extended key.  Consequently,
   177  // this function will return ErrDeriveHardFromPublic if a hardened child
   178  // extended key is requested from a public extended key.
   179  //
   180  // A hardened extended key is useful since, as previously mentioned, it requires
   181  // a parent private extended key to derive.  In other words, normal child
   182  // extended public keys can be derived from a parent public extended key (no
   183  // knowledge of the parent private key) whereas hardened extended keys may not
   184  // be.
   185  //
   186  // NOTE: There is an extremely small chance (< 1 in 2^127) the specific child
   187  // index does not derive to a usable child.  The ErrInvalidChild error will be
   188  // returned if this should occur, and the caller is expected to ignore the
   189  // invalid child and simply increment to the next index.
   190  func (k *ExtendedKey) Child(i uint32) (*ExtendedKey, error) {
   191  	// There are four scenarios that could happen here:
   192  	// 1) Private extended key -> Hardened child private extended key
   193  	// 2) Private extended key -> Non-hardened child private extended key
   194  	// 3) Public extended key -> Non-hardened child public extended key
   195  	// 4) Public extended key -> Hardened child public extended key (INVALID!)
   196  
   197  	// Case #4 is invalid, so error out early.
   198  	// A hardened child extended key may not be created from a public
   199  	// extended key.
   200  	isChildHardened := i >= HardenedKeyStart
   201  	if !k.isPrivate && isChildHardened {
   202  		return nil, ErrDeriveHardFromPublic
   203  	}
   204  
   205  	// The data used to derive the child key depends on whether or not the
   206  	// child is hardened per [BIP32].
   207  	//
   208  	// For hardened children:
   209  	//   0x00 || ser256(parentKey) || ser32(i)
   210  	//
   211  	// For normal children:
   212  	//   serP(parentPubKey) || ser32(i)
   213  	keyLen := 33
   214  	data := make([]byte, keyLen+4)
   215  	if isChildHardened {
   216  		// Case #1.
   217  		// When the child is a hardened child, the key is known to be a
   218  		// private key due to the above early return.  Pad it with a
   219  		// leading zero as required by [BIP32] for deriving the child.
   220  		copy(data[1:], k.key)
   221  	} else {
   222  		// Case #2 or #3.
   223  		// This is either a public or private extended key, but in
   224  		// either case, the data which is used to derive the child key
   225  		// starts with the secp256k1 compressed public key bytes.
   226  		copy(data, k.pubKeyBytes())
   227  	}
   228  	binary.BigEndian.PutUint32(data[keyLen:], i)
   229  
   230  	// Take the HMAC-SHA512 of the current key's chain code and the derived
   231  	// data:
   232  	//   I = HMAC-SHA512(Key = chainCode, Data = data)
   233  	hmac512 := hmac.New(sha512.New, k.chainCode)
   234  	hmac512.Write(data)
   235  	ilr := hmac512.Sum(nil)
   236  
   237  	// Split "I" into two 32-byte sequences Il and Ir where:
   238  	//   Il = intermediate key used to derive the child
   239  	//   Ir = child chain code
   240  	il := ilr[:len(ilr)/2]
   241  	childChainCode := ilr[len(ilr)/2:]
   242  
   243  	// Both derived public or private keys rely on treating the left 32-byte
   244  	// sequence calculated above (Il) as a 256-bit integer that must be
   245  	// within the valid range for a secp256k1 private key.  There is a small
   246  	// chance (< 1 in 2^127) this condition will not hold, and in that case,
   247  	// a child extended key can't be created for this index and the caller
   248  	// should simply increment to the next index.
   249  	ilNum := new(big.Int).SetBytes(il)
   250  	if ilNum.Cmp(koblitz.S256().N) >= 0 || ilNum.Sign() == 0 {
   251  		return nil, ErrInvalidChild
   252  	}
   253  
   254  	// The algorithm used to derive the child key depends on whether or not
   255  	// a private or public child is being derived.
   256  	//
   257  	// For private children:
   258  	//   childKey = parse256(Il) + parentKey
   259  	//
   260  	// For public children:
   261  	//   childKey = serP(point(parse256(Il)) + parentKey)
   262  	var isPrivate bool
   263  	var childKey []byte
   264  	if k.isPrivate {
   265  		// Case #1 or #2.
   266  		// Add the parent private key to the intermediate private key to
   267  		// derive the final child key.
   268  		//
   269  		// childKey = parse256(Il) + parenKey
   270  		keyNum := new(big.Int).SetBytes(k.key)
   271  		ilNum.Add(ilNum, keyNum)
   272  		ilNum.Mod(ilNum, koblitz.S256().N)
   273  		childKey = ilNum.Bytes()
   274  		isPrivate = true
   275  	} else {
   276  		// Case #3.
   277  		// Calculate the corresponding intermediate public key for
   278  		// intermediate private key.
   279  		ilx, ily := koblitz.S256().ScalarBaseMult(il)
   280  		if ilx.Sign() == 0 || ily.Sign() == 0 {
   281  			return nil, ErrInvalidChild
   282  		}
   283  
   284  		// Convert the serialized compressed parent public key into X
   285  		// and Y coordinates so it can be added to the intermediate
   286  		// public key.
   287  		pubKey, err := koblitz.ParsePubKey(k.key, koblitz.S256())
   288  		if err != nil {
   289  			return nil, err
   290  		}
   291  
   292  		// Add the intermediate public key to the parent public key to
   293  		// derive the final child key.
   294  		//
   295  		// childKey = serP(point(parse256(Il)) + parentKey)
   296  		childX, childY := koblitz.S256().Add(ilx, ily, pubKey.X, pubKey.Y)
   297  		pk := koblitz.PublicKey{Curve: koblitz.S256(), X: childX, Y: childY}
   298  		childKey = pk.SerializeCompressed()
   299  	}
   300  
   301  	// The fingerprint of the parent for the derived child is the first 4
   302  	// bytes of the RIPEMD160(SHA256(parentPubKey)).
   303  	parentFP := btcutil.Hash160(k.pubKeyBytes())[:4]
   304  	return newExtendedKey(k.version, childKey, childChainCode, parentFP,
   305  		k.depth+1, i, isPrivate), nil
   306  }
   307  
   308  // Neuter returns a new extended public key from this extended private key.  The
   309  // same extended key will be returned unaltered if it is already an extended
   310  // public key.
   311  //
   312  // As the name implies, an extended public key does not have access to the
   313  // private key, so it is not capable of signing transactions or deriving
   314  // child extended private keys.  However, it is capable of deriving further
   315  // child extended public keys.
   316  func (k *ExtendedKey) Neuter() (*ExtendedKey, error) {
   317  	// Already an extended public key.
   318  	if !k.isPrivate {
   319  		return k, nil
   320  	}
   321  
   322  	// Get the associated public extended key version bytes.
   323  	version, err := coinparam.HDPrivateKeyToPublicKeyID(k.version)
   324  	if err != nil {
   325  		return nil, err
   326  	}
   327  
   328  	// Convert it to an extended public key.  The key for the new extended
   329  	// key will simply be the pubkey of the current extended private key.
   330  	//
   331  	// This is the function N((k,c)) -> (K, c) from [BIP32].
   332  	return newExtendedKey(version, k.pubKeyBytes(), k.chainCode, k.parentFP,
   333  		k.depth, k.childNum, false), nil
   334  }
   335  
   336  // ECPubKey converts the extended key to a koblitz public key and returns it.
   337  func (k *ExtendedKey) ECPubKey() (*koblitz.PublicKey, error) {
   338  	return koblitz.ParsePubKey(k.pubKeyBytes(), koblitz.S256())
   339  }
   340  
   341  // ECPrivKey converts the extended key to a koblitz private key and returns it.
   342  // As you might imagine this is only possible if the extended key is a private
   343  // extended key (as determined by the IsPrivate function).  The ErrNotPrivExtKey
   344  // error will be returned if this function is called on a public extended key.
   345  func (k *ExtendedKey) ECPrivKey() (*koblitz.PrivateKey, error) {
   346  	if !k.isPrivate {
   347  		return nil, ErrNotPrivExtKey
   348  	}
   349  
   350  	privKey, _ := koblitz.PrivKeyFromBytes(koblitz.S256(), k.key)
   351  	return privKey, nil
   352  }
   353  
   354  // Address converts the extended key to a standard bitcoin pay-to-pubkey-hash
   355  // address for the passed network.
   356  func (k *ExtendedKey) Address(net *coinparam.Params) (*btcutil.AddressPubKeyHash, error) {
   357  	pkHash := btcutil.Hash160(k.pubKeyBytes())
   358  	return btcutil.NewAddressPubKeyHash(pkHash, net)
   359  }
   360  
   361  // paddedAppend appends the src byte slice to dst, returning the new slice.
   362  // If the length of the source is smaller than the passed size, leading zero
   363  // bytes are appended to the dst slice before appending src.
   364  func paddedAppend(size uint, dst, src []byte) []byte {
   365  	for i := 0; i < int(size)-len(src); i++ {
   366  		dst = append(dst, 0)
   367  	}
   368  	return append(dst, src...)
   369  }
   370  
   371  // String returns the extended key as a human-readable base58-encoded string.
   372  func (k *ExtendedKey) String() string {
   373  	if len(k.key) == 0 {
   374  		return "zeroed extended key"
   375  	}
   376  
   377  	var childNumBytes [4]byte
   378  	depthByte := byte(k.depth % 256)
   379  	binary.BigEndian.PutUint32(childNumBytes[:], k.childNum)
   380  
   381  	// The serialized format is:
   382  	//   version (4) || depth (1) || parent fingerprint (4)) ||
   383  	//   child num (4) || chain code (32) || key data (33) || checksum (4)
   384  	serializedBytes := make([]byte, 0, serializedKeyLen+4)
   385  	serializedBytes = append(serializedBytes, k.version...)
   386  	serializedBytes = append(serializedBytes, depthByte)
   387  	serializedBytes = append(serializedBytes, k.parentFP...)
   388  	serializedBytes = append(serializedBytes, childNumBytes[:]...)
   389  	serializedBytes = append(serializedBytes, k.chainCode...)
   390  	if k.isPrivate {
   391  		serializedBytes = append(serializedBytes, 0x00)
   392  		serializedBytes = paddedAppend(32, serializedBytes, k.key)
   393  	} else {
   394  		serializedBytes = append(serializedBytes, k.pubKeyBytes()...)
   395  	}
   396  
   397  	checkSum := chainhash.DoubleHashB(serializedBytes)[:4]
   398  	serializedBytes = append(serializedBytes, checkSum...)
   399  	return base58.Encode(serializedBytes)
   400  }
   401  
   402  // IsForNet returns whether or not the extended key is associated with the
   403  // passed bitcoin network.
   404  func (k *ExtendedKey) IsForNet(net *coinparam.Params) bool {
   405  	return bytes.Equal(k.version, net.HDPrivateKeyID[:]) ||
   406  		bytes.Equal(k.version, net.HDPublicKeyID[:])
   407  }
   408  
   409  // SetNet associates the extended key, and any child keys yet to be derived from
   410  // it, with the passed network.
   411  func (k *ExtendedKey) SetNet(net *coinparam.Params) {
   412  	if k.isPrivate {
   413  		k.version = net.HDPrivateKeyID[:]
   414  	} else {
   415  		k.version = net.HDPublicKeyID[:]
   416  	}
   417  }
   418  
   419  // zero sets all bytes in the passed slice to zero.  This is used to
   420  // explicitly clear private key material from memory.
   421  func zero(b []byte) {
   422  	lenb := len(b)
   423  	for i := 0; i < lenb; i++ {
   424  		b[i] = 0
   425  	}
   426  }
   427  
   428  // Zero manually clears all fields and bytes in the extended key.  This can be
   429  // used to explicitly clear key material from memory for enhanced security
   430  // against memory scraping.  This function only clears this particular key and
   431  // not any children that have already been derived.
   432  func (k *ExtendedKey) Zero() {
   433  	zero(k.key)
   434  	zero(k.pubKey)
   435  	zero(k.chainCode)
   436  	zero(k.parentFP)
   437  	k.version = nil
   438  	k.key = nil
   439  	k.depth = 0
   440  	k.childNum = 0
   441  	k.isPrivate = false
   442  }
   443  
   444  // NewMaster creates a new master node for use in creating a hierarchical
   445  // deterministic key chain.  The seed must be between 128 and 512 bits and
   446  // should be generated by a cryptographically secure random generation source.
   447  //
   448  // NOTE: There is an extremely small chance (< 1 in 2^127) the provided seed
   449  // will derive to an unusable secret key.  The ErrUnusable error will be
   450  // returned if this should occur, so the caller must check for it and generate a
   451  // new seed accordingly.
   452  func NewMaster(seed []byte, net *coinparam.Params) (*ExtendedKey, error) {
   453  	// Per [BIP32], the seed must be in range [MinSeedBytes, MaxSeedBytes].
   454  	if len(seed) < MinSeedBytes || len(seed) > MaxSeedBytes {
   455  		return nil, ErrInvalidSeedLen
   456  	}
   457  
   458  	// First take the HMAC-SHA512 of the master key and the seed data:
   459  	//   I = HMAC-SHA512(Key = "Bitcoin seed", Data = S)
   460  	hmac512 := hmac.New(sha512.New, masterKey)
   461  	hmac512.Write(seed)
   462  	lr := hmac512.Sum(nil)
   463  
   464  	// Split "I" into two 32-byte sequences Il and Ir where:
   465  	//   Il = master secret key
   466  	//   Ir = master chain code
   467  	secretKey := lr[:len(lr)/2]
   468  	chainCode := lr[len(lr)/2:]
   469  
   470  	// Ensure the key in usable.
   471  	secretKeyNum := new(big.Int).SetBytes(secretKey)
   472  	if secretKeyNum.Cmp(koblitz.S256().N) >= 0 || secretKeyNum.Sign() == 0 {
   473  		return nil, ErrUnusableSeed
   474  	}
   475  
   476  	parentFP := []byte{0x00, 0x00, 0x00, 0x00}
   477  	return newExtendedKey(net.HDPrivateKeyID[:], secretKey, chainCode,
   478  		parentFP, 0, 0, true), nil
   479  }
   480  
   481  // NewKeyFromString returns a new extended key instance from a base58-encoded
   482  // extended key.
   483  func NewKeyFromString(key string) (*ExtendedKey, error) {
   484  	// The base58-decoded extended key must consist of a serialized payload
   485  	// plus an additional 4 bytes for the checksum.
   486  	decoded := base58.Decode(key)
   487  	if len(decoded) != serializedKeyLen+4 {
   488  		return nil, ErrInvalidKeyLen
   489  	}
   490  
   491  	// The serialized format is:
   492  	//   version (4) || depth (1) || parent fingerprint (4)) ||
   493  	//   child num (4) || chain code (32) || key data (33) || checksum (4)
   494  
   495  	// Split the payload and checksum up and ensure the checksum matches.
   496  	payload := decoded[:len(decoded)-4]
   497  	checkSum := decoded[len(decoded)-4:]
   498  	expectedCheckSum := chainhash.DoubleHashB(payload)[:4]
   499  	if !bytes.Equal(checkSum, expectedCheckSum) {
   500  		return nil, ErrBadChecksum
   501  	}
   502  
   503  	// Deserialize each of the payload fields.
   504  	version := payload[:4]
   505  	depth := uint16(payload[4:5][0])
   506  	parentFP := payload[5:9]
   507  	childNum := binary.BigEndian.Uint32(payload[9:13])
   508  	chainCode := payload[13:45]
   509  	keyData := payload[45:78]
   510  
   511  	// The key data is a private key if it starts with 0x00.  Serialized
   512  	// compressed pubkeys either start with 0x02 or 0x03.
   513  	isPrivate := keyData[0] == 0x00
   514  	if isPrivate {
   515  		// Ensure the private key is valid.  It must be within the range
   516  		// of the order of the secp256k1 curve and not be 0.
   517  		keyData = keyData[1:]
   518  		keyNum := new(big.Int).SetBytes(keyData)
   519  		if keyNum.Cmp(koblitz.S256().N) >= 0 || keyNum.Sign() == 0 {
   520  			return nil, ErrUnusableSeed
   521  		}
   522  	} else {
   523  		// Ensure the public key parses correctly and is actually on the
   524  		// secp256k1 curve.
   525  		_, err := koblitz.ParsePubKey(keyData, koblitz.S256())
   526  		if err != nil {
   527  			return nil, err
   528  		}
   529  	}
   530  
   531  	return newExtendedKey(version, keyData, chainCode, parentFP, depth,
   532  		childNum, isPrivate), nil
   533  }
   534  
   535  // GenerateSeed returns a cryptographically secure random seed that can be used
   536  // as the input for the NewMaster function to generate a new master node.
   537  //
   538  // The length is in bytes and it must be between 16 and 64 (128 to 512 bits).
   539  // The recommended length is 32 (256 bits) as defined by the RecommendedSeedLen
   540  // constant.
   541  func GenerateSeed(length uint8) ([]byte, error) {
   542  	// Per [BIP32], the seed must be in range [MinSeedBytes, MaxSeedBytes].
   543  	if length < MinSeedBytes || length > MaxSeedBytes {
   544  		return nil, ErrInvalidSeedLen
   545  	}
   546  
   547  	buf := make([]byte, length)
   548  	_, err := rand.Read(buf)
   549  	if err != nil {
   550  		return nil, err
   551  	}
   552  
   553  	return buf, nil
   554  }