/** * @param Consensus $consensus * @param EcAdapterInterface $ecAdapter * @param ScriptCheckInterface $scriptCheck */ public function __construct(Consensus $consensus, EcAdapterInterface $ecAdapter, ScriptCheckInterface $scriptCheck) { $this->consensus = $consensus; $this->math = $ecAdapter->getMath(); $this->scriptCheck = $scriptCheck; $this->params = $consensus->getParams(); }
/** * @param Db $db * @param EcAdapterInterface $ecAdapter * @param Consensus $consensus * @param BlockCheckInterface $blockCheck */ public function __construct(Db $db, EcAdapterInterface $ecAdapter, Consensus $consensus, BlockCheckInterface $blockCheck) { $this->blockCheck = $blockCheck; $this->consensus = $consensus; $this->db = $db; $this->math = $ecAdapter->getMath(); }
/** * Headers constructor. * @param DbInterface $db * @param EcAdapterInterface $ecAdapter * @param ChainsInterface $chains * @param Consensus $consensus * @param ProofOfWork $proofOfWork */ public function __construct(DbInterface $db, EcAdapterInterface $ecAdapter, ChainsInterface $chains, Consensus $consensus, ProofOfWork $proofOfWork) { $this->db = $db; $this->math = $ecAdapter->getMath(); $this->chains = $chains; $this->consensus = $consensus; $this->proofOfWork = $proofOfWork; $this->headerCheck = new HeaderCheck($consensus, $ecAdapter, $proofOfWork); }
/** * Blocks constructor. * @param DbInterface $db * @param ConfigProviderInterface $config * @param EcAdapterInterface $ecAdapter * @param ChainsInterface $chains * @param Consensus $consensus */ public function __construct(DbInterface $db, ConfigProviderInterface $config, EcAdapterInterface $ecAdapter, ChainsInterface $chains, Consensus $consensus) { $this->db = $db; $this->config = $config; $this->math = $ecAdapter->getMath(); $this->chains = $chains; $this->consensus = $consensus; $this->blockCheck = new BlockCheck($consensus, $ecAdapter); }
/** * @param EcAdapterInterface $ecAdapter */ public function __construct(EcAdapterInterface $ecAdapter) { $this->ecAdapter = $ecAdapter; $this->math = $ecAdapter->getMath(); $this->vchFalse = new Buffer("", 0, $this->math); $this->vchTrue = new Buffer("", 1, $this->math); $this->int0 = Number::buffer($this->vchFalse, false, 4, $this->math)->getBuffer(); $this->int1 = Number::buffer($this->vchTrue, false, 1, $this->math)->getBuffer(); }
/** * @param $mnemonic * @return Buffer */ public function mnemonicToEntropy($mnemonic) { $math = $this->ecAdapter->getMath(); $words = explode(' ', $mnemonic); if ($math->cmp($math->mod(count($words), 3), 0) !== 0) { throw new \InvalidArgumentException('Invalid mnemonic'); } $bits = array(); foreach ($words as $word) { $idx = $this->wordList->getIndex($word); $bits[] = str_pad($math->baseConvert($idx, 10, 2), 11, '0', STR_PAD_LEFT); } $bits = implode('', $bits); $CS = strlen($bits) / 33; $ENT = strlen($bits) - $CS; $csBits = substr($bits, -1 * $CS); $entBits = substr($bits, 0, -1 * $CS); $binary = ''; $bitsInChar = 8; for ($i = 0; $i < $ENT; $i += $bitsInChar) { // Extract 8 bits at a time, convert to hex, pad, and convert to binary. $eBits = substr($entBits, $i, $bitsInChar); $binary .= hex2bin(str_pad($math->baseConvert($eBits, 2, 16), 2, '0', STR_PAD_LEFT)); } $entropy = new Buffer($binary, null, $math); if ($csBits !== $this->calculateChecksum($entropy, $CS)) { throw new \InvalidArgumentException('Checksum does not match'); } return $entropy; }
/** * @param \BitWasp\Bitcoin\Crypto\EcAdapter\Signature\SignatureInterface[] $signatures * @param \BitWasp\Bitcoin\Crypto\EcAdapter\Key\PublicKeyInterface[] $publicKeys * @param BufferInterface $messageHash * @return \SplObjectStorage */ public function link(array $signatures, array $publicKeys, BufferInterface $messageHash) { $sigCount = count($signatures); $storage = new \SplObjectStorage(); foreach ($signatures as $signature) { foreach ($publicKeys as $key) { if ($this->ecAdapter->verify($messageHash, $key, $signature)) { $storage->attach($key, $signature); if (count($storage) === $sigCount) { break 2; } break; } } } return $storage; }
/** * @param string $mnemonic * @return Buffer */ public function mnemonicToEntropy($mnemonic) { $math = $this->ecAdapter->getMath(); $wordList = $this->wordList; $words = explode(' ', $mnemonic); $n = count($wordList); $out = ''; $thirdWordCount = count($words) / 3; for ($i = 0; $i < $thirdWordCount; $i++) { list($word1, $word2, $word3) = array_slice($words, $math->mul(3, $i), 3); $index1 = $wordList->getIndex($word1); $index2 = $wordList->getIndex($word2); $index3 = $wordList->getIndex($word3); $x = $math->add($index1, $math->add($math->mul($n, $math->mod($index2 - $index1, $n)), $math->mul($n, $math->mul($n, $math->mod($index3 - $index2, $n))))); $out .= str_pad($math->decHex($x), 8, '0', STR_PAD_LEFT); } return Buffer::hex($out); }
/** * @param PrivateKeyInterface $key * @param ScriptInterface $scriptCode * @param int $sigVersion * @return TransactionSignature */ public function calculateSignature(PrivateKeyInterface $key, ScriptInterface $scriptCode, $sigVersion) { if ($sigVersion == 1) { $hasher = new V1Hasher($this->tx, $this->txOut->getValue()); } else { $hasher = new Hasher($this->tx); } $hash = $hasher->calculate($scriptCode, $this->nInput, $this->sigHashType); return new TransactionSignature($this->ecAdapter, $this->ecAdapter->sign($hash, $key, new Rfc6979($this->ecAdapter, $key, $hash, 'sha256')), $this->sigHashType); }
/** * @param ScriptInterface $script * @param Buffer $sigBuf * @param Buffer $keyBuf * @return bool * @throws ScriptRuntimeException * @throws \Exception */ private function checkSig(ScriptInterface $script, Buffer $sigBuf, Buffer $keyBuf) { $this->checkSignatureEncoding($sigBuf)->checkPublicKeyEncoding($keyBuf); try { $txSignature = TransactionSignatureFactory::fromHex($sigBuf->getHex()); $publicKey = PublicKeyFactory::fromHex($keyBuf->getHex()); return $this->ecAdapter->verify($this->transaction->getSignatureHash()->calculate($script, $this->inputToSign, $txSignature->getHashType()), $publicKey, $txSignature->getSignature()); } catch (\Exception $e) { return false; } }
/** * @param TransactionInterface $tx * @param $inputToExtract * @return $this */ public function extractSigs(TransactionInterface $tx, $inputToExtract) { $inputs = $tx->getInputs(); $parsed = $inputs[$inputToExtract]->getScript()->getScriptParser()->decode(); $size = count($parsed); switch ($this->getScriptType()) { case OutputClassifier::PAYTOPUBKEYHASH: // Supply signature and public key in scriptSig if ($size === 2) { $this->signatures = [TransactionSignatureFactory::fromHex($parsed[0]->getData(), $this->ecAdapter)]; $this->publicKeys = [PublicKeyFactory::fromHex($parsed[1]->getData(), $this->ecAdapter)]; } break; case OutputClassifier::PAYTOPUBKEY: // Only has a signature in the scriptSig if ($size === 1) { $this->signatures = [TransactionSignatureFactory::fromHex($parsed[0]->getData(), $this->ecAdapter)]; } break; case OutputClassifier::MULTISIG: $redeemScript = $this->getRedeemScript(); $keys = $this->scriptInfo->getKeys(); foreach ($keys as $idx => $key) { $this->setSignature($idx, null); } if ($size > 2 && $size <= $this->scriptInfo->getKeyCount() + 2) { $sigs = []; foreach ($keys as $key) { $sigs[$key->getPubKeyHash()->getHex()] = []; } // Extract Signatures (as buffers), then compile arrays of [pubkeyHash => signature] $sigHash = new Hasher($tx); foreach (array_slice($parsed, 1, -1) as $item) { /** @var \BitWasp\Bitcoin\Script\Parser\Operation $item */ if ($item->isPush()) { $txSig = TransactionSignatureFactory::fromHex($item->getData(), $this->ecAdapter); $linked = $this->ecAdapter->associateSigs([$txSig->getSignature()], $sigHash->calculate($redeemScript, $inputToExtract, $txSig->getHashType()), $keys); if (count($linked)) { $key = array_keys($linked)[0]; $sigs[$key] = array_merge($sigs[$key], [$txSig]); } } } // We have all the signatures from the tx now. array_shift the sigs for a public key, as it's encountered. foreach ($keys as $idx => $key) { $hash = $key->getPubKeyHash()->getHex(); $this->setSignature($idx, isset($sigs[$hash]) ? array_shift($sigs[$hash]) : null); } } break; } return $this; }
/** * @param \BitWasp\Bitcoin\Script\Interpreter\Number $sequence * @return bool */ public function checkSequence(\BitWasp\Bitcoin\Script\Interpreter\Number $sequence) { $math = $this->adapter->getMath(); $txSequence = $this->transaction->getInput($this->nInput)->getSequence(); if ($this->transaction->getVersion() < 2) { return false; } if ($math->cmp($math->bitwiseAnd($txSequence, TransactionInputInterface::SEQUENCE_LOCKTIME_DISABLE_FLAG), 0) !== 0) { return 0; } $mask = $math->bitwiseOr(TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, TransactionInputInterface::SEQUENCE_LOCKTIME_MASK); return $this->verifyLockTime($math->bitwiseAnd($txSequence, $mask), TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, Number::int($math->bitwiseAnd($sequence->getInt(), $mask))); }
/** * @param Consensus $consensus * @param EcAdapterInterface $ecAdapter * @param ProofOfWork $proofOfWork */ public function __construct(Consensus $consensus, EcAdapterInterface $ecAdapter, ProofOfWork $proofOfWork) { $this->consensus = $consensus; $this->math = $ecAdapter->getMath(); $this->pow = $proofOfWork; }
/** * @param Consensus $consensus * @param EcAdapterInterface $ecAdapter */ public function __construct(Consensus $consensus, EcAdapterInterface $ecAdapter) { $this->consensus = $consensus; $this->math = $ecAdapter->getMath(); }
/** * @param int $bytes * @return Buffer */ public function bytes($bytes) { $integer = $this->hmac->generate($this->ecAdapter->getGenerator()->getOrder()); return Buffer::int($integer, $bytes, $this->ecAdapter->getMath()); }
/** * Decodes a BIP32 path into actual 32bit sequence numbers and derives the child key * * @param string $path * @return HierarchicalKey * @throws \Exception */ public function derivePath($path) { $sequences = new HierarchicalKeySequence($this->ecAdapter->getMath()); return $this->deriveFromList($sequences->decodePath($path)); }
/** * @param PrivateKeyInterface $privKey * @param Buffer $hash * @param $sigHashType * @return TransactionSignature */ public function makeSignature(PrivateKeyInterface $privKey, Buffer $hash, $sigHashType) { return new TransactionSignature($this->ecAdapter, $this->ecAdapter->sign($hash, $privKey, $this->deterministicSignatures ? new Rfc6979($this->ecAdapter, $privKey, $hash, 'sha256') : new Random()), $sigHashType); }
public function compareChainStateWork(ChainState $a, ChainState $b) { return $this->adapter->getMath()->cmp($a->getChain()->getIndex()->getWork(), $b->getChain()->getIndex()->getWork()); }
/** * @param string $message * @param PrivateKeyInterface $privateKey * @return SignedMessage */ public function sign($message, PrivateKeyInterface $privateKey) { $hash = $this->calculateMessageHash($message); return new SignedMessage($message, $this->ecAdapter->signCompact($hash, $privateKey, new Rfc6979($this->ecAdapter, $privateKey, $hash, 'sha256'))); }
/** * @param int|string $sequence * @param bool $change * @return int|string */ public function getSequenceOffset($sequence, $change = false) { return Hash::sha256d(new Buffer(sprintf("%s:%s:%s", $sequence, $change ? '1' : '0', $this->getMPK()->getBinary()), null, $this->ecAdapter->getMath()))->getInt(); }