func (s *SeriesData) getPrivKeyFor(pubKey *hdkeychain.ExtendedKey) (*hdkeychain.ExtendedKey, error) { for i, key := range s.publicKeys { if key.String() == pubKey.String() { return s.privateKeys[i], nil } } return nil, newError(ErrUnknownPubKey, fmt.Sprintf("unknown public key '%s'", pubKey.String()), nil) }
// NewAdr creates a new, never before seen address, and increments the // DB counter as well as putting it in the ram Adrs store, and returns it func (ts *TxStore) NewAdr() (btcutil.Address, error) { if ts.Param == nil { return nil, fmt.Errorf("NewAdr error: nil param") } priv := new(hdkeychain.ExtendedKey) var err error var n uint32 var nAdr btcutil.Address n = uint32(len(ts.Adrs)) priv, err = ts.rootPrivKey.Child(n + hdkeychain.HardenedKeyStart) if err != nil { return nil, err } nAdr, err = priv.Address(ts.Param) if err != nil { return nil, err } // total number of keys (now +1) into 4 bytes var buf bytes.Buffer err = binary.Write(&buf, binary.BigEndian, n+1) if err != nil { return nil, err } // write to db file err = ts.StateDB.Update(func(btx *bolt.Tx) error { sta := btx.Bucket(BKTState) return sta.Put(KEYNumKeys, buf.Bytes()) }) if err != nil { return nil, err } // add in to ram. var ma MyAdr ma.PkhAdr = nAdr ma.KeyIdx = n ts.Adrs = append(ts.Adrs, ma) ts.localFilter.Add(ma.PkhAdr.ScriptAddress()) return nAdr, nil }
// 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) } if pubKey.String() != checkPubKey.String() { str := fmt.Sprintf("public key %v different than expected %v", pubKey, checkPubKey) return nil, nil, newError(ErrKeyMismatch, str, nil) } } } return pubKeys, privKeys, 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, addrType addressType) (*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, true, addrType) if err != nil { return nil, err } } else { pubKey, err := key.ECPubKey() if err != nil { return nil, err } managedAddr, err = newManagedAddressWithoutPrivKey(m, account, pubKey, true, addrType) if err != nil { return nil, err } } return managedAddr, nil }