/** * @return BufferInterface */ private function serialize() { if ($this->math->cmp($this->number, '0') === 0) { return new Buffer('', 0); } // Using array of integers instead of bytes $result = []; $negative = $this->math->cmp($this->number, 0) < 0; $abs = $negative ? $this->math->sub(0, $this->number) : $this->number; while ($this->math->cmp($abs, 0) > 0) { //array_unshift($result, (int)$this->math->bitwiseAnd($abs, 0xff)); $result[] = (int) $this->math->bitwiseAnd($abs, 0xff); $abs = $this->math->rightShift($abs, 8); } if ($result[count($result) - 1] & 0x80) { //array_unshift($result, $negative ? 0x80 : 0); $result[] = $negative ? 0x80 : 0; } else { if ($negative) { //$result[0] |= 0x80; $result[count($result) - 1] |= 0x80; } } $s = ''; foreach ($result as $i) { $s .= chr($i); } return new Buffer($s, null, $this->math); }
/** * @param Parser $parser * @return CompactSignature * @throws ParserOutOfRange */ public function fromParser(Parser &$parser) { try { list($byte, $r, $s) = $this->getTemplate()->parse($parser); $recoveryFlags = $this->math->sub($byte, 27); if ($recoveryFlags < 0 || $recoveryFlags > 7) { throw new \InvalidArgumentException('invalid signature type'); } $isCompressed = $this->math->bitwiseAnd($recoveryFlags, 4) != 0; $recoveryId = $recoveryFlags - ($isCompressed ? 4 : 0); } catch (ParserOutOfRange $e) { throw new ParserOutOfRange('Failed to extract full signature from parser'); } $signature = new CompactSignature($r, $s, $recoveryId, $isCompressed); return $signature; }
/** * @param \BitWasp\Bitcoin\Script\Interpreter\Number $sequence * @return bool */ private function checkSequence(Number $sequence) { $txSequence = $this->transaction->getInput($this->inputToSign)->getSequence(); if ($this->transaction->getVersion() < 2) { return false; } if ($this->math->cmp($this->math->bitwiseAnd($txSequence, TransactionInputInterface::SEQUENCE_LOCKTIME_DISABLE_FLAG), 0) !== 0) { return 0; } $mask = $this->math->bitwiseOr(TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, TransactionInputInterface::SEQUENCE_LOCKTIME_MASK); return $this->verifyLockTime($this->math->bitwiseAnd($txSequence, $mask), TransactionInputInterface::SEQUENCE_LOCKTIME_TYPE_FLAG, Number::int($this->math->bitwiseAnd($sequence->getInt(), $mask))); }
/** * @return Buffer */ private function serialize() { if ($this->math->cmp($this->number, '0') === 0) { return new Buffer('', 4); } // Using array of integers instead of bytes $result = []; $negative = $this->math->cmp($this->number, 0) < 0; $abs = $negative ? $this->math->sub(0, $this->number) : $this->number; while ($this->math->cmp($abs, 0) > 0) { array_unshift($result, (int) $this->math->bitwiseAnd($abs, 0xff)); $abs = $this->math->rightShift($abs, 8); } if ($result[0] & 0x80) { array_unshift($result, $negative ? 0x80 : 0x0); } else { if ($negative) { array_unshift($result, 0x80); } } return new Buffer(array_reduce($result, function ($agg, $current) { return $agg . chr($current); }), 4, $this->math); }
/** * @param int $flag * @return bool */ public function checkFlag($flag) { return $this->math->cmp($this->math->bitwiseAnd($this->flags->getFlags(), self::UPDATE_MASK), $flag) === 0; }