// validateAndDecryptSeriesKeys checks that the length of the public and private key // slices is the same, decrypts them, ensures the non-nil private keys have a matching // public key and returns them. // // This function must be called with the Pool's manager unlocked. func validateAndDecryptKeys(rawPubKeys, rawPrivKeys [][]byte, p *Pool) (pubKeys, privKeys []*hdkeychain.ExtendedKey, err error) { pubKeys = make([]*hdkeychain.ExtendedKey, len(rawPubKeys)) privKeys = make([]*hdkeychain.ExtendedKey, len(rawPrivKeys)) if len(pubKeys) != len(privKeys) { return nil, nil, newError(ErrKeysPrivatePublicMismatch, "the pub key and priv key arrays should have the same number of elements", nil) } for i, encryptedPub := range rawPubKeys { pubKey, err := p.decryptExtendedKey(waddrmgr.CKTPublic, encryptedPub) if err != nil { return nil, nil, err } pubKeys[i] = pubKey encryptedPriv := rawPrivKeys[i] var privKey *hdkeychain.ExtendedKey if encryptedPriv == nil { privKey = nil } else { privKey, err = p.decryptExtendedKey(waddrmgr.CKTPrivate, encryptedPriv) if err != nil { return nil, nil, err } } privKeys[i] = privKey if privKey != nil { checkPubKey, err := privKey.Neuter() if err != nil { str := fmt.Sprintf("cannot neuter key %v", privKey) return nil, nil, newError(ErrKeyNeuter, str, err) } key, err := pubKey.String() if err != nil { return nil, nil, err } checkKey, err := pubKey.String() if err != nil { return nil, nil, err } if key != checkKey { str := fmt.Sprintf("public key %v different than expected %v", pubKey, checkPubKey) return nil, nil, newError(ErrKeyMismatch, str, nil) } } } return pubKeys, privKeys, nil }
func (s *SeriesData) getPrivKeyFor(pubKey *hdkeychain.ExtendedKey) (*hdkeychain.ExtendedKey, error) { pKey, err := pubKey.String() if err != nil { return nil, err } for i, key := range s.publicKeys { k, err := key.String() if err != nil { return nil, err } if k == pKey { return s.privateKeys[i], nil } } return nil, newError(ErrUnknownPubKey, fmt.Sprintf("unknown public key '%s'", pKey), nil) }
// newManagedAddressFromExtKey returns a new managed address based on the passed // account and extended key. The managed address will have access to the // private and public keys if the provided extended key is private, otherwise it // will only have access to the public key. func newManagedAddressFromExtKey(m *Manager, account uint32, key *hdkeychain.ExtendedKey) (*managedAddress, error) { // Create a new managed address based on the public or private key // depending on whether the generated key is private. var managedAddr *managedAddress if key.IsPrivate() { privKey, err := key.ECPrivKey() if err != nil { return nil, err } // Ensure the temp private key big integer is cleared after use. managedAddr, err = newManagedAddress(m, account, privKey) zero.BigInt(privKey.GetD()) if err != nil { return nil, err } } else { pubKey, err := key.ECPubKey() if err != nil { return nil, err } managedAddr, err = newManagedAddressWithoutPrivKey(m, account, pubKey, true) if err != nil { return nil, err } } return managedAddr, nil }