Пример #1
0
 /**
  * @param Math $math
  * @param Opcodes $opcodes
  * @param BufferInterface|null $buffer
  */
 public function __construct(Math $math, Opcodes $opcodes, BufferInterface $buffer = null)
 {
     if ($buffer !== null) {
         $this->script = $buffer->getBinary();
     }
     $this->math = $math;
     $this->opcodes = $opcodes;
 }
Пример #2
0
 /**
  * Encode a given hex string in base58
  *
  * @param BufferInterface $binary
  * @return string
  * @throws \Exception
  */
 public static function encode(BufferInterface $binary)
 {
     $size = $binary->getSize();
     if ($binary->getBinary() === '') {
         return '';
     }
     $math = Bitcoin::getMath();
     $orig = $binary->getBinary();
     $decimal = $binary->getInt();
     $return = '';
     while ($math->cmp($decimal, 0) > 0) {
         list($decimal, $rem) = $math->divQr($decimal, 58);
         $return .= self::$base58chars[$rem];
     }
     $return = strrev($return);
     //leading zeros
     for ($i = 0; $i < $size && $orig[$i] === ""; $i++) {
         $return = '1' . $return;
     }
     return $return;
 }
Пример #3
0
 /**
  * @param BufferInterface $sig
  * @return bool
  * @throws SignatureNotCanonical
  */
 public static function isDERSignature(BufferInterface $sig)
 {
     $checkVal = function ($fieldName, $start, $length, $binaryString) {
         if ($length === 0) {
             throw new SignatureNotCanonical('Signature ' . $fieldName . ' length is zero');
         }
         $typePrefix = ord(substr($binaryString, $start - 2, 1));
         if ($typePrefix !== 0x2) {
             throw new SignatureNotCanonical('Signature ' . $fieldName . ' value type mismatch');
         }
         $val = substr($binaryString, $start, $length);
         $vAnd = $val[0] & chr(0x80);
         if (ord($vAnd) === 128) {
             throw new SignatureNotCanonical('Signature ' . $fieldName . ' value is negative');
         }
         if ($length > 1 && $val[0] === "" && !ord($val[1] & chr(0x80))) {
             throw new SignatureNotCanonical('Signature ' . $fieldName . ' value excessively padded');
         }
     };
     $bin = $sig->getBinary();
     $size = $sig->getSize();
     if ($size < 9) {
         throw new SignatureNotCanonical('Signature too short');
     }
     if ($size > 73) {
         throw new SignatureNotCanonical('Signature too long');
     }
     if (ord($bin[0]) !== 0x30) {
         throw new SignatureNotCanonical('Signature has wrong type');
     }
     if (ord($bin[1]) !== $size - 3) {
         throw new SignatureNotCanonical('Signature has wrong length marker');
     }
     $lenR = ord($bin[3]);
     $startR = 4;
     if (5 + $lenR >= $size) {
         throw new SignatureNotCanonical('Signature S length misplaced');
     }
     $lenS = ord($bin[5 + $lenR]);
     $startS = 4 + $lenR + 2;
     if ($lenR + $lenS + 7 !== $size) {
         throw new SignatureNotCanonical('Signature R+S length mismatch');
     }
     $checkVal('R', $startR, $lenR, $bin);
     $checkVal('S', $startS, $lenS, $bin);
     return true;
 }
Пример #4
0
 /**
  * @param BufferInterface $publicKey
  * @return bool
  */
 public static function isCompressedOrUncompressed(BufferInterface $publicKey)
 {
     $vchPubKey = $publicKey->getBinary();
     if ($publicKey->getSize() < 33) {
         return false;
     }
     if (ord($vchPubKey[0]) === 0x4) {
         if ($publicKey->getSize() !== 65) {
             // Invalid length for uncompressed key
             return false;
         }
     } elseif (in_array($vchPubKey[0], array(hex2bin(self::KEY_COMPRESSED_EVEN), hex2bin(self::KEY_COMPRESSED_ODD)))) {
         if ($publicKey->getSize() !== 33) {
             return false;
         }
     } else {
         return false;
     }
     return true;
 }
Пример #5
0
 /**
  * @param BufferInterface $buffer
  * @return int
  */
 private function parseBuffer(BufferInterface $buffer)
 {
     $size = $buffer->getSize();
     if ($size === 0) {
         return '0';
     }
     $chars = array_map(function ($binary) {
         return ord($binary);
     }, str_split($buffer->getBinary(), 1));
     $result = 0;
     for ($i = 0; $i < $size; $i++) {
         $mul = $this->math->mul($i, 8);
         $byte = $this->math->leftShift($chars[$i], $mul);
         $result = $this->math->bitwiseOr($result, $byte);
     }
     if ($chars[count($chars) - 1] & 0x80) {
         $mask = gmp_strval(gmp_com($this->math->leftShift(0x80, 8 * ($size - 1))), 10);
         return $this->math->sub(0, $this->math->bitwiseAnd($result, $mask));
     }
     return $result;
 }
Пример #6
0
 /**
  * Determine whether the sighash byte appended to the signature encodes
  * a valid sighash type.
  *
  * @param BufferInterface $signature
  * @return bool
  */
 public function isDefinedHashtypeSignature(BufferInterface $signature)
 {
     if ($signature->getSize() === 0) {
         return false;
     }
     $binary = $signature->getBinary();
     $nHashType = ord(substr($binary, -1)) & ~SigHash::ANYONECANPAY;
     $math = $this->adapter->getMath();
     return !($math->cmp($nHashType, SigHash::ALL) < 0 || $math->cmp($nHashType, SigHash::SINGLE) > 0);
 }
Пример #7
0
 /**
  * Do HMAC hashing on $data and $salt
  *
  * @param string $algo
  * @param BufferInterface $data
  * @param BufferInterface $salt
  * @return BufferInterface
  */
 public static function hmac($algo, BufferInterface $data, BufferInterface $salt)
 {
     return new Buffer(hash_hmac($algo, $data->getBinary(), $salt->getBinary(), true));
 }
Пример #8
0
 /**
  * @param BufferInterface $buffer
  * @return bool
  */
 public function isKnownHeader(BufferInterface $buffer)
 {
     $binary = $buffer->getBinary();
     foreach (array_keys($this->segments) as $segment) {
         if (isset($this->hashStorage[$segment][$binary])) {
             return true;
         }
     }
     return false;
 }
Пример #9
0
 /**
  * @param BufferInterface $buffer
  * @return int
  */
 public function getHeightFromHash(BufferInterface $buffer)
 {
     $binary = $buffer->getBinary();
     foreach ($this->segments as $segment) {
         $hashes = $this->container->getHashes($segment);
         if (isset($hashes[$binary])) {
             return $hashes[$binary];
         }
     }
     throw new \RuntimeException('Hash not found');
 }
Пример #10
0
 /**
  * @param BufferInterface $hash
  * @return $this
  */
 public function markReceived(BufferInterface $hash)
 {
     unset($this->inFlight[$hash->getBinary()]);
     return $this;
 }
Пример #11
0
 /**
  * @param BufferInterface $msg32
  * @param PrivateKey $privateKey
  * @return CompactSignature
  */
 private function doSignCompact(BufferInterface $msg32, PrivateKey $privateKey)
 {
     $sig_t = '';
     /** @var resource $sig_t */
     if (1 !== secp256k1_ecdsa_sign_recoverable($this->context, $msg32->getBinary(), $privateKey->getBinary(), $sig_t)) {
         throw new \RuntimeException('Secp256k1: failed to sign');
     }
     $recid = '';
     $ser = '';
     if (!secp256k1_ecdsa_recoverable_signature_serialize_compact($this->context, $sig_t, $ser, $recid)) {
         throw new \RuntimeException('Failed to obtain recid');
     }
     unset($ser);
     return new CompactSignature($this, $sig_t, $recid, $privateKey->isCompressed());
 }
Пример #12
0
 /**
  * @param BufferInterface $script
  * @param Opcodes|null $opCodes
  */
 public function __construct(BufferInterface $script = null, Opcodes $opCodes = null)
 {
     $this->script = $script instanceof BufferInterface ? $script->getBinary() : '';
     $this->opCodes = $opCodes ?: new Opcodes();
 }
Пример #13
0
 /**
  * @param PublicKeyInterface $publicKey
  * @return bool
  */
 public function checkInvolvesKey(PublicKeyInterface $publicKey)
 {
     return $publicKey->getPubKeyHash()->getBinary() === $this->hash->getBinary();
 }
Пример #14
0
 /**
  * @param BufferInterface $hash
  * @param int $numAncestors
  * @return array
  */
 public function findSuperMajorityInfoByHash(BufferInterface $hash, $numAncestors = 1000)
 {
     $this->fetchLftRgtByHash->execute(['hash' => $hash->getBinary()]);
     $id = $this->fetchLftRgtByHash->fetch(\PDO::FETCH_ASSOC);
     $this->fetchSuperMajorityVersions->execute(['lft' => $id['lft'], 'rgt' => $id['rgt']]);
     $stream = $this->fetchSuperMajorityVersions->fetchAll(\PDO::FETCH_COLUMN);
     return $stream;
 }
Пример #15
0
 /**
  * @param int $opCode
  * @param BufferInterface $pushData
  * @return bool
  * @throws \Exception
  */
 public function checkMinimalPush($opCode, BufferInterface $pushData)
 {
     $pushSize = $pushData->getSize();
     $binary = $pushData->getBinary();
     if ($pushSize === 0) {
         return $opCode === Opcodes::OP_0;
     } elseif ($pushSize === 1) {
         $first = ord($binary[0]);
         if ($first >= 1 && $first <= 16) {
             return $opCode === Opcodes::OP_1 + ($first - 1);
         } elseif ($first === 0x81) {
             return $opCode === Opcodes::OP_1NEGATE;
         }
     } elseif ($pushSize <= 75) {
         return $opCode === $pushSize;
     } elseif ($pushSize <= 255) {
         return $opCode === Opcodes::OP_PUSHDATA1;
     } elseif ($pushSize <= 65535) {
         return $opCode === Opcodes::OP_PUSHDATA2;
     }
     return true;
 }