| 223 | } |
| 224 | |
| 225 | bool CKey::Derive(CKey& keyChild, ChainCode &ccChild, unsigned int nChild, const ChainCode& cc) const { |
| 226 | assert(IsValid()); |
| 227 | assert(IsCompressed()); |
| 228 | unsigned char out[64]; |
| 229 | LockObject(out); |
| 230 | if ((nChild >> 31) == 0) { |
| 231 | CPubKey pubkey = GetPubKey(); |
| 232 | assert(pubkey.begin() + 33 == pubkey.end()); |
| 233 | BIP32Hash(cc, nChild, *pubkey.begin(), pubkey.begin()+1, out); |
| 234 | } else { |
| 235 | assert(begin() + 32 == end()); |
| 236 | BIP32Hash(cc, nChild, 0, begin(), out); |
| 237 | } |
| 238 | memcpy(ccChild.begin(), out+32, 32); |
| 239 | memcpy((unsigned char*)keyChild.begin(), begin(), 32); |
| 240 | bool ret = secp256k1_ec_privkey_tweak_add(secp256k1_context_sign, (unsigned char*)keyChild.begin(), out); |
| 241 | UnlockObject(out); |
| 242 | keyChild.fCompressed = true; |
| 243 | keyChild.fValid = ret; |
| 244 | return ret; |
| 245 | } |
| 246 | |
| 247 | bool CExtKey::Derive(CExtKey &out, unsigned int nChild) const { |
| 248 | out.nDepth = nDepth + 1; |