/** * @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 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)])]); }