/** * @param Buffer|string $data * @return PublicKey * @throws \Exception */ public function parse($data) { $buffer = (new Parser($data))->getBuffer(); if (!in_array($buffer->getSize(), [PublicKey::LENGTH_COMPRESSED, PublicKey::LENGTH_UNCOMPRESSED], true)) { throw new \Exception('Invalid hex string, must match size of compressed or uncompressed public key'); } return $this->ecAdapter->publicKeyFromBuffer($buffer); }
/** * @param SignatureInterface $signature * @return BufferInterface */ public function serialize(SignatureInterface $signature) { $math = $this->ecAdapter->getMath(); // Ensure that the R and S hex's are of even length $rBin = pack('H*', $math->decHex($signature->getR())); $sBin = pack('H*', $math->decHex($signature->getS())); // Pad R and S if their highest bit is flipped, ie, // they are negative. $rt = $rBin[0] & pack('H*', '80'); if (ord($rt) === 128) { $rBin = pack('H*', '00') . $rBin; } $st = $sBin[0] & pack('H*', '80'); if (ord($st) === 128) { $sBin = pack('H*', '00') . $sBin; } return $this->getOuterTemplate()->write([0x30, $this->getInnerTemplate()->write([0x2, new Buffer($rBin, null, $math), 0x2, new Buffer($sBin, null, $math)])]); }
/** * @param Peer $sender * @param TransactionSignatureInterface $txSig * @return TransactionSignatureInterface */ public function fixSig(Peer $sender, TransactionSignatureInterface $txSig, &$wasMalleated = false) { $sig = $txSig->getSignature(); if (!$this->adapter->validateSignatureElement($sig->getS(), true)) { $ip = $sender->getRemoteAddr()->getIp(); if (!isset($this->violators[$ip])) { $this->violators[$sender->getRemoteAddr()->getIp()] = 1; } else { $this->violators[$sender->getRemoteAddr()->getIp()]++; } $wasMalleated = true; $this->counter++; $txSig = new TransactionSignature($this->adapter, new Signature($this->adapter, $sig->getR(), $this->math->sub($this->order, $sig->getS())), $txSig->getHashType()); if (!$this->adapter->validateSignatureElement($txSig->getSignature()->getS(), true)) { die('failed to produce a low-s signature'); } } return $txSig; }
/** * @param int|string $tweak * @return PublicKeyInterface */ public function tweakMul($tweak) { $point = $this->point->mul($tweak); return $this->ecAdapter->getPublicKey($point, $this->compressed); }
/** * @param NetworkInterface $network * @return string */ public function toWif(NetworkInterface $network = null) { $network = $network ?: Bitcoin::getNetwork(); $serializer = new WifPrivateKeySerializer($this->ecAdapter->getMath(), new PrivateKeySerializer($this->ecAdapter)); return $serializer->serialize($network, $this); }
/** * @param Parser $parser * @return PrivateKey */ public function fromParser(Parser $parser) { $compressed = $this->haveNextCompressed; $this->haveNextCompressed = false; return $this->ecAdapter->getPrivateKey($parser->readBytes(32)->getInt(), $compressed); }
/** * @param $string * @return CompactSignature * @throws ParserOutOfRange */ public function parse($string) { return $this->fromParser(new Parser($string, $this->ecAdapter->getMath())); }