// Derive a key from another.
// Uses HMAC(key=key, data=reason)
// Not to be confused with DeriveSymmetricKey which has hmac inputs swapped.
// This one makes sense for derivation from secrets used only to derive from.
489254
func DeriveFromSecret(inKey [32]byte, reason DeriveReason) (outKey [32]byte, err error) {
	if len(reason) < 8 {
		return outKey, KeyGenError{Msg: "reason must be at least 8 bytes"}
	}

	mac := hmac.New(sha256.New, inKey[:])
	_, err = mac.Write([]byte(reason))
	if err != nil {
		return outKey, err
	}
	out := mac.Sum(nil)

	if copy(outKey[:], out) != len(outKey) {
		return outKey, KeyGenError{Msg: "derived key of wrong size"}
	}

	return outKey, nil
}
535568
func (f *FastTeamChainLoader) deriveKeysForApplication(m libkb.MetaContext, app keybase1.TeamApplication, arg fastLoadArg, state *keybase1.FastTeamData) (keys []keybase1.TeamApplicationKey, err error) {

	var didLatest bool
	doKey := func(gen keybase1.PerTeamKeyGeneration) error {
		var key keybase1.TeamApplicationKey
		key, err = f.deriveKeyForApplicationAtGeneration(m, app, gen, state)
		if err != nil {
			return err
		}
		keys = append(keys, key)
		if gen == state.LatestKeyGeneration {
			didLatest = true
		}
		return nil
	}

	if arg.NeedLatestKey {
		// This debug is useful to have since it will spell out which version is the latest in the log
		// if the caller asked for latest.
		m.Debug("FastTeamChainLoader#deriveKeysForApplication: sending back latest at key generation %d", state.LatestKeyGeneration)
	}

	for _, gen := range arg.KeyGenerationsNeeded {
		if err = doKey(gen); err != nil {
			return nil, err
		}
	}
	if !didLatest && arg.NeedLatestKey {
		if err = doKey(state.LatestKeyGeneration); err != nil {
			return nil, err
		}
	}
	return keys, nil
}
92943
func deriveRevision(c *scannedConfigs) string {
	keys := make([]string, 0, len(c.contentHashMap))
	for k := range c.contentHashMap {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	hsh := sha256.New()
	for _, k := range keys {
		fmt.Fprintf(hsh, "%s\n%s\n", k, c.contentHashMap[k])
	}
	digest := hsh.Sum(nil)
	return hex.EncodeToString(digest[:])[:40]
}
403680
func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) {
	return accounts.Account{}, accounts.ErrNotSupported
}
1025389
func (ek *EncryptedKey) DecryptSymmetricKey(cert *tls.Certificate) (cipher.Block, error) {
	if len(cert.Certificate) < 1 {
		return nil, fmt.Errorf("decryption tls.Certificate has no public certs attached")
	}

	// The EncryptedKey may or may not include X509Data (certificate).
	// If included, the EncryptedKey certificate:
	// - is FYI only (fail if it does not match the SP certificate)
	// - is NOT used to decrypt CipherData
	if ek.X509Data != "" {
		if encCert, err := base64.StdEncoding.DecodeString(ek.X509Data); err != nil {
			return nil, fmt.Errorf("error decoding EncryptedKey certificate: %v", err)
		} else if !bytes.Equal(cert.Certificate[0], encCert) {
			return nil, fmt.Errorf("key decryption attempted with mismatched cert, SP cert(%.11s), assertion cert(%.11s)",
				debugKeyFp(cert.Certificate[0]), debugKeyFp(encCert))
		}
	}

	cipherText, err := base64.StdEncoding.DecodeString(ek.CipherValue)
	if err != nil {
		return nil, err
	}

	switch pk := cert.PrivateKey.(type) {
	case *rsa.PrivateKey:
		var h hash.Hash

		switch ek.EncryptionMethod.DigestMethod.Algorithm {
		case "", MethodSHA1:
			h = sha1.New() // default
		case MethodSHA256:
			h = sha256.New()
		case MethodSHA512:
			h = sha512.New()
		default:
			return nil, fmt.Errorf("unsupported digest algorithm: %v",
				ek.EncryptionMethod.DigestMethod.Algorithm)
		}

		switch ek.EncryptionMethod.Algorithm {
		case "":
			return nil, fmt.Errorf("missing encryption algorithm")
		case MethodRSAOAEP, MethodRSAOAEP2:
			pt, err := rsa.DecryptOAEP(h, rand.Reader, pk, cipherText, nil)
			if err != nil {
				return nil, fmt.Errorf("rsa internal error: %v", err)
			}

			b, err := aes.NewCipher(pt)
			if err != nil {
				return nil, err
			}

			return b, nil
		default:
			return nil, fmt.Errorf("unsupported encryption algorithm: %s", ek.EncryptionMethod.Algorithm)
		}
	}
	return nil, fmt.Errorf("no cipher for decoding symmetric key")
}
1345024
func StringifyKey(key interface{}) string {
	switch key {
	// For named keys we want to handle explicitly

	default:
		// Stringify keys
		switch k := key.(type) {
		case string:
			return k
		case fmt.Stringer:
			return k.String()
		default:
			return fmt.Sprintf("%v", key)
		}
	}
}
1190758
func deriveCompare_(this, that *boat) int {
	if this == nil {
		if that == nil {
			return 0
		}
		return -1
	}
	if that == nil {
		return 1
	}
	if c := deriveCompare_i(this.length, that.length); c != 0 {
		return c
	}
	return 0
}
488013
func (ks *KeyStore) GenerateSymmetricKey(topic Topic, address PssAddress, addToCache bool) (string, error) {
	keyid, err := ks.w.GenerateSymKey()
	if err == nil {
		ks.addSymmetricKeyToPool(keyid, topic, address, addToCache, false)
	}
	return keyid, err
}
577167
func (w *WalletKit) DeriveNextKey(ctx context.Context,
	req *KeyReq) (*signrpc.KeyDescriptor, error) {

	nextKeyDesc, err := w.cfg.KeyRing.DeriveNextKey(
		keychain.KeyFamily(req.KeyFamily),
	)
	if err != nil {
		return nil, err
	}

	return &signrpc.KeyDescriptor{
		KeyLoc: &signrpc.KeyLocator{
			KeyFamily: int32(nextKeyDesc.Family),
			KeyIndex:  int32(nextKeyDesc.Index),
		},
		RawKeyBytes: nextKeyDesc.PubKey.SerializeCompressed(),
	}, nil
}
1197837
func deriveAccountKey(coinTypeKey *hdkeychain.ExtendedKey,
	account uint32) (*hdkeychain.ExtendedKey, error) {

	// Enforce maximum account number.
	if account > MaxAccountNum {
		err := managerError(ErrAccountNumTooHigh, errAcctTooHigh, nil)
		return nil, err
	}

	// Derive the account key as a child of the coin type key.
	return coinTypeKey.Child(account + hdkeychain.HardenedKeyStart)
}
390522
func (f *FastTeamChainLoader) deriveSeedAtGeneration(m libkb.MetaContext, gen keybase1.PerTeamKeyGeneration, state *keybase1.FastTeamData) (seed keybase1.PerTeamKeySeed, err error) {

	seed, ok := state.Chain.PerTeamKeySeedsVerified[gen]
	if ok {
		return seed, nil
	}
	var tmp keybase1.PerTeamKeySeed
	tmp, ok = state.PerTeamKeySeedsUnverified[gen]
	if !ok {
		// See CORE-9207. We can hit this case if we previously loaded a parent team for verifying a subteam
		// name before we were members of the team, and then later get added to the team, and then try to
		// reload the team. We didn't have boxes from the first time around, so just force a full reload.
		// It's inefficient but it's a very rare case.
		return seed, NewFTLMissingSeedError(gen)
	}

	ptkChain, ok := state.Chain.PerTeamKeys[gen]
	if !ok {
		return seed, NewFastLoadError(fmt.Sprintf("no per team key public halves at generation %d", gen))
	}

	km, err := NewTeamKeyManagerWithSecret(tmp, gen)
	if err != nil {
		return seed, err
	}

	sigKey, err := km.SigningKey()
	if err != nil {
		return seed, err
	}

	if !ptkChain.SigKID.SecureEqual(sigKey.GetKID()) {
		m.Debug("sig KID gen:%v (local) %v != %v (chain)", gen, sigKey.GetKID(), ptkChain.SigKID)
		return seed, NewFastLoadError(fmt.Sprintf("wrong team key (sig) found at generation %v", gen))
	}

	encKey, err := km.EncryptionKey()
	if err != nil {
		return seed, err
	}

	if !ptkChain.EncKID.SecureEqual(encKey.GetKID()) {
		m.Debug("enc KID gen:%v (local) %v != %v (chain)", gen, encKey.GetKID(), ptkChain.EncKID)
		return seed, NewFastLoadError(fmt.Sprintf("wrong team key (enc) found at generation %v", gen))
	}

	// write back to cache
	seed = tmp
	state.Chain.PerTeamKeySeedsVerified[gen] = seed
	return seed, err
}
279837
func DeriveGen(downstream interface{}, upstream interface{}, gens ...Gen) Gen {
	biMapper := NewBiMapper(downstream, upstream)

	if len(gens) != len(biMapper.UpTypes) {
		panic(fmt.Sprintf("Expected %d generators != %d", len(biMapper.UpTypes), len(gens)))
	}

	resultType := reflect.TypeOf([]interface{}{})
	if len(biMapper.DownTypes) == 1 {
		resultType = biMapper.DownTypes[0]
	}

	derived := &derivedGen{
		biMapper:   biMapper,
		upGens:     gens,
		resultType: resultType,
	}
	return derived.Generate
}
497622
func (b *BtcWalletKeyRing) DerivePrivKey(keyDesc KeyDescriptor) (*btcec.PrivateKey, error) {
	var key *btcec.PrivateKey

	db := b.wallet.Database()
	err := walletdb.Update(db, func(tx walletdb.ReadWriteTx) error {
		addrmgrNs := tx.ReadWriteBucket(waddrmgrNamespaceKey)

		scope, err := b.keyScope()
		if err != nil {
			return err
		}

		// If the account doesn't exist, then we may need to create it
		// for the first time in order to derive the keys that we
		// require.
		err = b.createAccountIfNotExists(
			addrmgrNs, keyDesc.Family, scope,
		)
		if err != nil {
			return err
		}

		// If the public key isn't set or they have a non-zero index,
		// then we know that the caller instead knows the derivation
		// path for a key.
		if keyDesc.PubKey == nil || keyDesc.Index > 0 {
			// Now that we know the account exists, we can safely
			// derive the full private key from the given path.
			path := waddrmgr.DerivationPath{
				Account: uint32(keyDesc.Family),
				Branch:  0,
				Index:   uint32(keyDesc.Index),
			}
			addr, err := scope.DeriveFromKeyPath(addrmgrNs, path)
			if err != nil {
				return err
			}

			key, err = addr.(waddrmgr.ManagedPubKeyAddress).PrivKey()
			if err != nil {
				return err
			}

			return nil
		}

		// If the public key isn't nil, then this indicates that we
		// need to scan for the private key, assuming that we know the
		// valid key family.
		nextPath := waddrmgr.DerivationPath{
			Account: uint32(keyDesc.Family),
			Branch:  0,
			Index:   0,
		}

		// We'll now iterate through our key range in an attempt to
		// find the target public key.
		//
		// TODO(roasbeef): possibly move scanning into wallet to allow
		// to be parallelized
		for i := 0; i < MaxKeyRangeScan; i++ {
			// Derive the next key in the range and fetch its
			// managed address.
			addr, err := scope.DeriveFromKeyPath(
				addrmgrNs, nextPath,
			)
			if err != nil {
				return err
			}
			managedAddr := addr.(waddrmgr.ManagedPubKeyAddress)

			// If this is the target public key, then we'll return
			// it directly back to the caller.
			if managedAddr.PubKey().IsEqual(keyDesc.PubKey) {
				key, err = managedAddr.PrivKey()
				if err != nil {
					return err
				}

				return nil
			}

			// This wasn't the target key, so roll forward and try
			// the next one.
			nextPath.Index++
		}

		// If we reach this point, then we we're unable to derive the
		// private key, so return an error back to the user.
		return ErrCannotDerivePrivKey
	})
	if err != nil {
		return nil, err
	}

	return key, nil
}
659419
func (s *ScopedKeyManager) DeriveFromKeyPath(ns walletdb.ReadBucket,
	kp DerivationPath) (ManagedAddress, error) {

	s.mtx.Lock()
	defer s.mtx.Unlock()

	extKey, err := s.deriveKeyFromPath(
		ns, kp.Account, kp.Branch, kp.Index, !s.rootManager.IsLocked(),
	)
	if err != nil {
		return nil, err
	}

	return s.keyToManaged(extKey, kp.Account, kp.Branch, kp.Index)
}
663452
func (m *Multisig) Key(seed Trytes, index uint64, security SecurityLevel, spongeFunc ...SpongeFunction) (Trytes, error) {
	h := GetSpongeFunc(spongeFunc, kerl.NewKerl)

	subseed, err := signing.Subseed(seed, index, h)
	if err != nil {
		return "", err
	}

	keyTrits, err := signing.Key(subseed, security, h)
	if err != nil {
		return "", err
	}

	return MustTritsToTrytes(keyTrits), nil
}
653791
func (w *trezorDriver) Derive(path accounts.DerivationPath) (common.Address, error) {
	return w.trezorDerive(path)
}
329926
func Key(subseed Trits, securityLevel SecurityLevel, spongeFunc ...SpongeFunction) (Trits, error) {
	h := GetSpongeFunc(spongeFunc, kerl.NewKerl)
	defer h.Reset()

	keyLength := KeyFragmentLength * int(securityLevel)
	key := make(Trits, keyLength)

	err := h.Absorb(subseed)
	if err != nil {
		return nil, err
	}

	key, err = h.Squeeze(keyLength)
	if err != nil {
		return nil, err
	}

	h.Reset()

	for i := 0; i < KeyFragmentLength*int(securityLevel); i += HashTrinarySize {
		if err := h.Absorb(key[i : i+HashTrinarySize]); err != nil {
			return nil, err
		}

		buf, err := h.Squeeze(HashTrinarySize)
		if err != nil {
			return nil, err
		}
		copy(key[i:], buf)

		h.Reset()
	}

	return key, nil
}