예제 #1
0
 /**
  * @param PublicKey $publicKey
  * @return Buffer
  */
 private function doSerialize(PublicKey $publicKey)
 {
     $math = $this->ecAdapter->getMath();
     $point = $publicKey->getPoint();
     $compressed = $publicKey->isCompressed();
     $parser = new Parser('', $math);
     $parser->writeBytes(1, $this->getPrefix($compressed, $point));
     $compressed ? $parser->writeBytes(32, Buffer::int($point->getX(), null, $math)) : $parser->writeBytes(32, Buffer::int($point->getX(), null, $math))->writeBytes(32, Buffer::int($point->getY(), null, $math));
     return $parser->getBuffer();
 }
예제 #2
0
 /**
  * @return bool
  */
 public function isMultisig()
 {
     if (count($this->decoded) < 3) {
         return false;
     }
     $final = end($this->decoded);
     if (!$final || !$final->isPush()) {
         return false;
     }
     $script = new Script($final->getData());
     $decoded = $script->getScriptParser()->decode();
     $count = count($decoded);
     $mOp = $decoded[0];
     $nOp = $decoded[$count - 2];
     if ($mOp->isPush() || $nOp->isPush()) {
         return false;
     }
     if ($mOp->getOp() < Opcodes::OP_0 || $nOp->getOp() > Opcodes::OP_16) {
         return false;
     }
     /** @var Operation[] $keys */
     $keys = array_slice($decoded, 1, -2);
     $keysValid = true;
     foreach ($keys as $key) {
         $keysValid &= $key->isPush() && PublicKey::isCompressedOrUncompressed($key->getData());
     }
     return $keysValid;
 }
예제 #3
0
 /**
  * @param BufferInterface $publicKey
  * @param int $flags
  * @return $this
  * @throws \Exception
  */
 public function checkPublicKeyEncoding(BufferInterface $publicKey, $flags)
 {
     if (($flags & Interpreter::VERIFY_STRICTENC) != 0 && !PublicKey::isCompressedOrUncompressed($publicKey)) {
         throw new ScriptRuntimeException(Interpreter::VERIFY_STRICTENC, 'Public key with incorrect encoding');
     }
     return $this;
 }
예제 #4
0
 /**
  * Attempt to calculate the public key recovery param by trial and error
  *
  * @param int|string     $r
  * @param int|string     $s
  * @param Buffer $messageHash
  * @param PublicKey $publicKey
  * @return int
  * @throws \Exception
  */
 public function calcPubKeyRecoveryParam($r, $s, Buffer $messageHash, PublicKey $publicKey)
 {
     $Q = $publicKey->getPoint();
     for ($i = 0; $i < 4; $i++) {
         try {
             $recover = $this->recover($messageHash, new CompactSignature($this, $r, $s, $i, $publicKey->isCompressed()));
             if ($recover->getPoint()->equals($Q)) {
                 return $i;
             }
         } catch (\Exception $e) {
             continue;
         }
     }
     throw new \Exception('Failed to find valid recovery factor');
 }
예제 #5
0
 /**
  * @param Buffer $publicKey
  * @return $this
  * @throws \Exception
  */
 public function checkPublicKeyEncoding(Buffer $publicKey)
 {
     if ($this->flags->checkFlags(self::VERIFY_STRICTENC) && !PublicKey::isCompressedOrUncompressed($publicKey)) {
         throw new ScriptRuntimeException(self::VERIFY_STRICTENC, 'Public key with incorrect encoding');
     }
     return $this;
 }
예제 #6
0
 /**
  * @return bool
  */
 public function isMultisig()
 {
     $count = count($this->decoded);
     if ($count <= 3) {
         return false;
     }
     $mOp = $this->decoded[0];
     $nOp = $this->decoded[$count - 2];
     $checksig = $this->decoded[$count - 1];
     if ($mOp->isPush() || $nOp->isPush() || $checksig->isPush()) {
         return false;
     }
     /** @var Operation[] $vKeys */
     $vKeys = array_slice($this->decoded, 1, -2);
     foreach ($vKeys as $key) {
         if (!$key->isPush() || !PublicKey::isCompressedOrUncompressed($key->getData())) {
             return false;
         }
     }
     return $mOp->getOp() >= Opcodes::OP_0 && $nOp->getOp() <= Opcodes::OP_16 && $checksig->getOp() === Opcodes::OP_CHECKMULTISIG;
 }