Exemple #1
0
 public function verifies($hash, Signature $signature)
 {
     if (extension_loaded('gmp') && USE_EXT == 'GMP') {
         $G = $this->generator;
         $n = $this->generator->getOrder();
         $point = $this->point;
         $r = $signature->getR();
         $s = $signature->getS();
         if (gmp_cmp($r, 1) < 0 || gmp_cmp($r, gmp_sub($n, 1)) > 0) {
             return false;
         }
         if (gmp_cmp($s, 1) < 0 || gmp_cmp($s, gmp_sub($n, 1)) > 0) {
             return false;
         }
         $c = NumberTheory::inverse_mod($s, $n);
         $u1 = gmp_Utils::gmp_mod2(gmp_mul($hash, $c), $n);
         $u2 = gmp_Utils::gmp_mod2(gmp_mul($r, $c), $n);
         $xy = Point::add(Point::mul($u1, $G), Point::mul($u2, $point));
         $v = gmp_Utils::gmp_mod2($xy->getX(), $n);
         if (gmp_cmp($v, $r) == 0) {
             return true;
         } else {
             return false;
         }
     } else {
         if (extension_loaded('bcmath') && USE_EXT == 'BCMATH') {
             $G = $this->generator;
             $n = $this->generator->getOrder();
             $point = $this->point;
             $r = $signature->getR();
             $s = $signature->getS();
             if (bccomp($r, 1) == -1 || bccomp($r, bcsub($n, 1)) == 1) {
                 return false;
             }
             if (bccomp($s, 1) == -1 || bccomp($s, bcsub($n, 1)) == 1) {
                 return false;
             }
             $c = NumberTheory::inverse_mod($s, $n);
             $u1 = bcmod(bcmul($hash, $c), $n);
             $u2 = bcmod(bcmul($r, $c), $n);
             $xy = Point::add(Point::mul($u1, $G), Point::mul($u2, $point));
             $v = bcmod($xy->getX(), $n);
             if (bccomp($v, $r) == 0) {
                 return true;
             } else {
                 return false;
             }
         } else {
             throw new ErrorException("Please install BCMATH or GMP");
         }
     }
 }
 public function GOST_verifies($hash, Signature $signature)
 {
     if (extension_loaded('gmp') && USE_EXT == 'GMP') {
         $G = $this->generator;
         //P
         $n = $this->generator->getOrder();
         //q
         $point = $this->point;
         //Q
         $r = $signature->getR();
         $s = $signature->getS();
         if (gmp_cmp($r, 1) < 0 || gmp_cmp($r, gmp_sub($n, 1)) > 0) {
             return false;
         }
         if (gmp_cmp($s, 1) < 0 || gmp_cmp($s, gmp_sub($n, 1)) > 0) {
             return false;
         }
         //step 3 GOST
         $e = gmp_Utils::gmp_mod2($hash, $n);
         if (gmp_cmp($e, '0') === 0) {
             $e = gmp_init('1');
         }
         // step 4 GOST
         $v = gmp_strval(gmp_invert($e, $n));
         // step 5 GOST
         $z1 = gmp_Utils::gmp_mod2(gmp_mul($s, $v), $n);
         $z2 = gmp_Utils::gmp_mod2(gmp_mul(gmp_neg($r), $v), $n);
         // step 6 GOST
         $C = Point::add(Point::mul($z1, $G), Point::mul($z2, $point));
         $R = gmp_Utils::gmp_mod2($C->getX(), $n);
         if (0) {
             echo "n - " . $n . "\n";
             echo "h - " . $hash . "\n";
             echo "e - " . gmp_Utils::gmp_dechex($e) . "\n";
             echo "v - " . gmp_Utils::gmp_dechex($v) . "\n";
             echo "r - " . $r . "\n";
             echo "s - " . $s . "\n";
             echo "z1 - " . gmp_Utils::gmp_dechex($z1) . "\nz2 - " . gmp_Utils::gmp_dechex($z2) . "\n";
             echo "Q - " . $point . "\nG - " . $G . "\n";
             echo "C - " . $C . "\nR - " . $R . "\n";
         }
         if (gmp_cmp($R, $r) == 0) {
             return true;
         } else {
             return false;
         }
     } else {
         throw new ErrorException("Please install GMP");
     }
 }
 /**
  * Encode Signature
  *
  * This function accepts a signature object, and information about
  * the txout being spent, and the relevant key for signing, and
  * encodes the signature in DER format.
  *
  * @param    \Signature $signature
  * @return    string
  */
 public static function encode_signature(\Signature $signature)
 {
     // Pad r and s to 64 characters.
     $rh = str_pad(BitcoinLib::hex_encode($signature->getR()), 64, '0', STR_PAD_LEFT);
     $sh = str_pad(BitcoinLib::hex_encode($signature->getS()), 64, '0', STR_PAD_LEFT);
     // Check if the first byte of each has its highest bit set,
     $t1 = unpack("H*", pack('H*', substr($rh, 0, 2)) & pack('H*', '80'));
     $t2 = unpack("H*", pack('H*', substr($sh, 0, 2)) & pack('H*', '80'));
     // if so, the result != 00, and must be padded.
     $r = $t1[1] !== '00' ? '00' . $rh : $rh;
     $s = $t2[1] !== '00' ? '00' . $sh : $sh;
     // Create the signature.
     $der_sig = '30' . self::_dec_to_bytes(4 + (strlen($r) + strlen($s)) / 2, 1) . '02' . self::_dec_to_bytes(strlen($r) / 2, 1) . $r . '02' . self::_dec_to_bytes(strlen($s) / 2, 1) . $s . '01';
     return $der_sig;
 }