/** * @param EcAdapterInterface $ecAdapter * @param $int * @param bool $compressed * @throws InvalidPrivateKey */ public function __construct(EcAdapterInterface $ecAdapter, $int, $compressed = false) { $buffer = Buffer::hex($ecAdapter->getMath()->decHex($int), 32); if (false === $ecAdapter->validatePrivateKey($buffer)) { throw new InvalidPrivateKey('Invalid private key - must be less than curve order.'); } $this->ecAdapter = $ecAdapter; $this->secretMultiplier = $int; $this->setCompressed($compressed); }
/** * Derive a child key * * @param $sequence * @return HierarchicalKey * @throws \Exception */ public function deriveChild($sequence) { $chain = Buffer::hex($this->ecAdapter->getMath()->decHex($this->getChainCode()), 32); $hash = Hash::hmac('sha512', $this->getHmacSeed($sequence), $chain); $offset = $hash->slice(0, 32); $chain = $hash->slice(32); if (false === $this->ecAdapter->validatePrivateKey($offset)) { return $this->deriveChild($sequence + 1); } return new HierarchicalKey($this->ecAdapter, $this->getDepth() + 1, $this->getChildFingerprint(), $sequence, $chain->getInt(), $this->isPrivate() ? $this->ecAdapter->privateKeyAdd($this->getPrivateKey(), $offset->getInt()) : $this->ecAdapter->publicKeyAdd($this->getPublicKey(), $offset->getInt())); }