/** * @param SignatureInterface $signature * @return Buffer */ public function serialize(SignatureInterface $signature) { $math = $this->math; // 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), 0x2, new Buffer($sBin)])]); }
/** * @param PublicKeyInterface $publicKey * @param SignatureInterface $signature * @param Buffer $messageHash * @return bool */ public function verify(Buffer $messageHash, PublicKeyInterface $publicKey, SignatureInterface $signature) { $n = $this->getGenerator()->getOrder(); $math = $this->getMath(); $generator = $this->getGenerator(); if ($math->cmp($signature->getR(), 1) < 1 || $math->cmp($signature->getR(), $math->sub($n, 1)) > 0) { return false; } if ($math->cmp($signature->getS(), 1) < 1 || $math->cmp($signature->getS(), $math->sub($n, 1)) > 0) { return false; } $c = $math->inverseMod($signature->getS(), $n); $u1 = $math->mod($math->mul($messageHash->getInt(), $c), $n); $u2 = $math->mod($math->mul($signature->getR(), $c), $n); $xy = $generator->mul($u1)->add($publicKey->getPoint()->mul($u2)); $v = $math->mod($xy->getX(), $n); return $math->cmp($v, $signature->getR()) == 0; }
/** * @param Buffer $messageHash * @param PublicKeyInterface $publicKey * @param SignatureInterface $signature * @return bool * @throws \Exception */ public function verify(Buffer $messageHash, PublicKeyInterface $publicKey, SignatureInterface $signature) { $ret = \secp256k1_ecdsa_verify($messageHash->getBinary(), $signature->getBuffer()->getBinary(), $publicKey->getBuffer()->getBinary()); if ($ret === -1) { throw new \Exception('Secp256k1 verify: Invalid public key'); } else { if ($ret === -2) { throw new \Exception('Secp256k1 verify: Invalid signature'); } } return $ret === 1 ? true : false; }