예제 #1
0
 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");
     }
 }
function recoverPubKey($r, $s, $e, $recoveryFlags, $G)
{
    $isYEven = ($recoveryFlags & 1) != 0;
    $isSecondKey = ($recoveryFlags & 2) != 0;
    $curve = $G->getCurve();
    $signature = new Signature($r, $s);
    // Precalculate (p + 1) / 4 where p is the field order
    static $p_over_four;
    // XXX just assuming only one curve/prime will be used
    if (!$p_over_four) {
        $p_over_four = gmp_div(gmp_add($curve->getPrime(), 1), 4);
    }
    // 1.1 Compute x
    if (!$isSecondKey) {
        $x = $r;
    } else {
        $x = gmp_add($r, $G->getOrder());
    }
    // 1.3 Convert x to point
    $alpha = gmp_mod(gmp_add(gmp_add(gmp_pow($x, 3), gmp_mul($curve->getA(), $x)), $curve->getB()), $curve->getPrime());
    $beta = NumberTheory::modular_exp($alpha, $p_over_four, $curve->getPrime());
    // If beta is even, but y isn't or vice versa, then convert it,
    // otherwise we're done and y == beta.
    if (isBignumEven($beta) == $isYEven) {
        $y = gmp_sub($curve->getPrime(), $beta);
    } else {
        $y = $beta;
    }
    // 1.4 Check that nR is at infinity (implicitly done in construtor)
    $R = new Point($curve, $x, $y, $G->getOrder());
    $point_negate = function ($p) {
        return new Point($p->curve, $p->x, gmp_neg($p->y), $p->order);
    };
    // 1.6.1 Compute a candidate public key Q = r^-1 (sR - eG)
    $rInv = NumberTheory::inverse_mod($r, $G->getOrder());
    $eGNeg = $point_negate(Point::mul($e, $G));
    $Q = Point::mul($rInv, Point::add(Point::mul($s, $R), $eGNeg));
    // 1.6.2 Test Q as a public key
    $Qk = new PublicKey($G, $Q);
    if ($Qk->verifies($e, $signature)) {
        return $Qk;
    }
    return false;
}
예제 #3
0
 public static function mul($x2, Point $p1)
 {
     $e = $x2;
     if (self::cmp($p1, self::INFINITY) == 0) {
         return self::INFINITY;
     }
     if ($p1->order != null) {
         $e = gmp_mod($e, $p1->order);
     }
     if (gmp_cmp($e, 0) == 0) {
         return self::INFINITY;
     }
     if (gmp_cmp($e, 0) > 0) {
         $e3 = gmp_mul(3, $e);
         $negative_self = new Point($p1->curve, $p1->x, gmp_neg($p1->y), $p1->order);
         $i = gmp_div(self::leftmost_bit($e3), 2);
         $result = $p1;
         while (gmp_cmp($i, 1) > 0) {
             $result = self::double($result);
             if (gmp_cmp(gmp_and($e3, $i), 0) != 0 && gmp_cmp(gmp_and($e, $i), 0) == 0) {
                 $result = self::add($result, $p1);
             }
             if (gmp_cmp(gmp_and($e3, $i), 0) == 0 && gmp_cmp(gmp_and($e, $i), 0) != 0) {
                 $result = self::add($result, $negative_self);
             }
             $i = gmp_div($i, 2);
         }
         return $result;
     }
 }
 /**
  * Returns the negative of a Math_Integer number: -1 * $i1
  *
  * @param object Math_Integer $int1
  * @return object Math_Integer on success, PEAR_Error otherwise
  * @access public
  */
 function &neg(&$int1)
 {
     /*{{{*/
     if (PEAR::isError($err = Math_IntegerOp::_validInt($int1))) {
         return $err;
     }
     switch (MATH_INTLIB) {
         /*{{{*/
         case 'gmp':
             $tmp = gmp_strval(gmp_neg($int1->getValue()));
             break;
         case 'bcmath':
             $tmp = bcmul(-1, $int1->getValue());
             break;
         case 'std':
             $tmp = -1 * $int1->getValue();
             break;
     }
     /*}}}*/
     return new Math_Integer($tmp);
 }
예제 #5
0
파일: mostInOne.php 프로젝트: badlamer/hhvm
// gmp_jacobi
echo gmp_jacobi("1", "3") . "\n";
echo gmp_jacobi("2", "3") . "\n";
// gmp_legendre
echo gmp_legendre("1", "3") . "\n";
echo gmp_legendre("2", "3") . "\n";
// gmp_mod
$mod = gmp_mod("8", "3");
echo gmp_strval($mod) . "\n";
// gmp_mul
$mul = gmp_mul("12345678", "2000");
echo gmp_strval($mul) . "\n";
// gmp_neg
$neg1 = gmp_neg("1");
echo gmp_strval($neg1) . "\n";
$neg2 = gmp_neg("-1");
echo gmp_strval($neg2) . "\n";
// gmp_nextprime
$prime1 = gmp_nextprime(10);
// next prime number greater than 10
$prime2 = gmp_nextprime(-1000);
// next prime number greater than -1000
echo gmp_strval($prime1) . "\n";
echo gmp_strval($prime2) . "\n";
// gmp_or
$or1 = gmp_or("0xfffffff2", "4");
echo gmp_strval($or1, 16) . "\n";
$or2 = gmp_or("0xfffffff2", "2");
echo gmp_strval($or2, 16) . "\n";
// gmp_perfect_square
var_dump(gmp_perfect_square("9"));
예제 #6
0
 public function parse(DateTimeParseContext $context, $text, $position)
 {
     $length = strlen($text);
     if ($position === $length) {
         return ~$position;
     }
     if ($position < 0 || $position >= $length) {
         throw new \OutOfRangeException();
     }
     $sign = $text[$position];
     $negative = false;
     $positive = false;
     if ($sign === $context->getDecimalStyle()->getPositiveSign()) {
         if ($this->signStyle->parse(true, $context->isStrict(), $this->minWidth === $this->maxWidth) === false) {
             return ~$position;
         }
         $positive = true;
         $position++;
     } else {
         if ($sign === $context->getDecimalStyle()->getNegativeSign()) {
             if ($this->signStyle->parse(false, $context->isStrict(), $this->minWidth === $this->maxWidth) === false) {
                 return ~$position;
             }
             $negative = true;
             $position++;
         } else {
             if ($this->signStyle == SignStyle::ALWAYS() && $context->isStrict()) {
                 return ~$position;
             }
         }
     }
     $effMinWidth = $context->isStrict() || $this->isFixedWidth($context) ? $this->minWidth : 1;
     $minEndPos = $position + $effMinWidth;
     if ($minEndPos > $length) {
         return ~$position;
     }
     $effMaxWidth = ($context->isStrict() || $this->isFixedWidth($context) ? $this->maxWidth : 9) + Math::max($this->subsequentWidth, 0);
     $total = 0;
     $totalBig = null;
     $pos = $position;
     for ($pass = 0; $pass < 2; $pass++) {
         $maxEndPos = Math::min($pos + $effMaxWidth, $length);
         while ($pos < $maxEndPos) {
             $ch = $text[$pos++];
             $digit = $context->getDecimalStyle()->convertToDigit($ch);
             if ($digit < 0) {
                 $pos--;
                 if ($pos < $minEndPos) {
                     return ~$position;
                     // need at least min width digits
                 }
                 break;
             }
             if ($pos - $position > 18) {
                 if ($totalBig === null) {
                     $totalBig = \gmp_init($total);
                 }
                 $totalBig = \gmp_add(\gmp_mul($totalBig, "10"), \gmp_init($digit));
             } else {
                 $total = $total * 10 + $digit;
             }
         }
         if ($this->subsequentWidth > 0 && $pass === 0) {
             // re-parse now we know the correct width
             $parseLen = $pos - $position;
             $effMaxWidth = Math::max($effMinWidth, $parseLen - $this->subsequentWidth);
             $pos = $position;
             $total = 0;
             $totalBig = null;
         } else {
             break;
         }
     }
     if ($negative) {
         if ($totalBig !== null) {
             if (\gmp_cmp($totalBig, "0") === 0 && $context->isStrict()) {
                 return ~($position - 1);
                 // minus zero not allowed
             }
             $totalBig = \gmp_neg($totalBig);
         } else {
             if ($total === 0 && $context->isStrict()) {
                 return ~($position - 1);
                 // minus zero not allowed
             }
             $total = -$total;
         }
     } else {
         if ($this->signStyle == SignStyle::EXCEEDS_PAD() && $context->isStrict()) {
             $parseLen = $pos - $position;
             if ($positive) {
                 if ($parseLen <= $this->minWidth) {
                     return ~($position - 1);
                     // '+' only parsed if minWidth exceeded
                 }
             } else {
                 if ($parseLen > $this->minWidth) {
                     return ~$position;
                     // '+' must be parsed if minWidth exceeded
                 }
             }
         }
     }
     if ($totalBig !== null) {
         if (gmp_cmp($totalBig, "-9223372036854775808") < 0 || gmp_cmp($totalBig, "9223372036854775807") > 0) {
             // overflow, parse 1 less digit
             $totalBig = gmp_div($totalBig, "10");
             $pos--;
         }
         return $this->setValue($context, gmp_intval($totalBig), $position, $pos);
     }
     return $this->setValue($context, $total, $position, $pos);
 }
예제 #7
0
 public function getPubKeyWithRS($flag, $R, $S, $hash)
 {
     $isCompressed = false;
     if ($flag < 27 || $flag >= 35) {
         return false;
     }
     if ($flag >= 31) {
         $isCompressed = true;
         $flag -= 4;
     }
     $recid = $flag - 27;
     //step 1.1
     $x = null;
     $x = gmp_add(gmp_init($R, 16), gmp_mul($this->n, gmp_div_q(gmp_init($recid, 10), gmp_init(2, 10))));
     //step 1.3
     $y = null;
     if (1 == $flag % 2) {
         $gmpY = $this->calculateYWithX(gmp_strval($x, 16), '02');
         if (null != $gmpY) {
             $y = gmp_init($gmpY, 16);
         }
     } else {
         $gmpY = $this->calculateYWithX(gmp_strval($x, 16), '03');
         if (null != $gmpY) {
             $y = gmp_init($gmpY, 16);
         }
     }
     if (null == $y) {
         return null;
     }
     $Rpt = array('x' => $x, 'y' => $y);
     //step 1.6.1
     //calculate r^-1 (S*Rpt - eG)
     $eG = $this->mulPoint($hash, $this->G);
     $eG['y'] = gmp_mod(gmp_neg($eG['y']), $this->p);
     $SR = $this->mulPoint($S, $Rpt);
     $pubKey = $this->mulPoint(gmp_strval(gmp_invert(gmp_init($R, 16), $this->n), 16), $this->addPoints($SR, $eG));
     $pubKey['x'] = gmp_strval($pubKey['x'], 16);
     $pubKey['y'] = gmp_strval($pubKey['y'], 16);
     while (strlen($pubKey['x']) < 64) {
         $pubKey['x'] = '0' . $pubKey['x'];
     }
     while (strlen($pubKey['y']) < 64) {
         $pubKey['y'] = '0' . $pubKey['y'];
     }
     $derPubKey = $this->getDerPubKeyWithPubKeyPoints($pubKey, $isCompressed);
     if ($this->checkSignaturePoints($derPubKey, $R, $S, $hash)) {
         return $derPubKey;
     } else {
         return false;
     }
 }
예제 #8
0
파일: ED25519.php 프로젝트: fpoirotte/pssht
 protected static function isOnCurve($P)
 {
     $curve = \fpoirotte\Pssht\ED25519::getInstance();
     list($x, $y) = $P;
     $x2 = gmp_mul($x, $x);
     $y2 = gmp_mul($y, $y);
     $t = gmp_mod(gmp_sub(gmp_sub(gmp_add(gmp_neg($x2), $y2), 1), gmp_mul($curve->d, gmp_mul($x2, $y2))), $curve->q);
     return !gmp_cmp($t, 0);
 }
예제 #9
0
파일: gmp_neg.php 프로젝트: badlamer/hhvm
<?php

var_dump(gmp_intval(gmp_neg(0)));
var_dump(gmp_intval(gmp_neg(1)));
var_dump(gmp_intval(gmp_neg(-1)));
var_dump(gmp_intval(gmp_neg("-1")));
var_dump(gmp_intval(gmp_neg("")));
var_dump(gmp_intval(gmp_neg(0)));
$n = gmp_init("0");
var_dump(gmp_intval(gmp_neg($n)));
$n = gmp_init("12345678901234567890");
var_dump(gmp_strval(gmp_neg($n)));
var_dump(gmp_neg(1, 1));
var_dump(gmp_neg());
var_dump(gmp_neg(array()));
echo "Done\n";
예제 #10
0
 /**
  * This method returns the result of negating this object's value.
  *
  * @access public
  * @static
  * @param IInteger\Type $x                                  the operand
  * @return IInteger\Type                                    the result
  */
 public static function negate(IInteger\Type $x) : IInteger\Type
 {
     return IInteger\Type::box(gmp_strval(gmp_neg($x->unbox())));
 }
예제 #11
0
파일: Integer.php 프로젝트: sop/asn1
 protected static function _decodeFromDER(Identifier $identifier, $data, &$offset)
 {
     $idx = $offset;
     $length = Length::expectFromDER($data, $idx);
     $bytes = substr($data, $idx, $length->length());
     $idx += $length->length();
     $neg = ord($bytes[0]) & 0x80;
     // negative, apply inversion of two's complement
     if ($neg) {
         $len = strlen($bytes);
         for ($i = 0; $i < $len; $i++) {
             $bytes[$i] = ~$bytes[$i];
         }
     }
     $num = gmp_init(bin2hex($bytes), 16);
     // negative, apply addition of two's complement
     // and produce negative result
     if ($neg) {
         $num = gmp_neg($num + 1);
     }
     $offset = $idx;
     // late static binding since enumerated extends integer type
     return new static(gmp_strval($num, 10));
 }
예제 #12
0
 /**
  * Negates the number
  *
  * @return \Chippyash\Type\Number\GMPIntType Fluent Interface
  */
 public function negate()
 {
     $this->value = gmp_neg($this->value);
     return $this;
 }
예제 #13
0
파일: gmp.php 프로젝트: wikimedia/avro
 /**
  * @param int[] $bytes array of ascii codes of bytes to decode
  * @return string represenation of decoded long.
  */
 static function decode_long_from_array($bytes)
 {
     $b = array_shift($bytes);
     $g = gmp_init($b & 0x7f);
     $shift = 7;
     while (0 != ($b & 0x80)) {
         $b = array_shift($bytes);
         $g = gmp_or($g, self::shift_left($b & 0x7f, $shift));
         $shift += 7;
     }
     $val = gmp_xor(self::shift_right($g, 1), gmp_neg(gmp_and($g, 1)));
     return gmp_strval($val);
 }
예제 #14
0
 /**
  * Negates the value.
  *
  * @return BigInteger
  */
 public function negate() : BigInteger
 {
     $calculatedValue = gmp_neg($this->value);
     return $this->assignValue($calculatedValue);
 }
예제 #15
0
	public function size()
	{
		if( !$this->valid ) { return 0; }
		return gmp_intval( gmp_add( $this->net_broadcast_long, gmp_neg( $this->net_addr_long )));
	}
예제 #16
0
 /**
  * Creates a new decimal which is a result of a division of $a by $b.
  *
  * @param Decimal2 $a
  * @param Decimal2 $b
  * @return Decimal2
  */
 public static function div(Decimal2 $a, Decimal2 $b)
 {
     $strA = strval($a);
     $strB = strval($b);
     $sign_a = '-' === $strA[0] ? -1 : 1;
     $sign_b = '-' === $strB[0] ? -1 : 1;
     $ret = new Decimal2('0');
     $ret->cents = gmp_strval(gmp_div_q(gmp_add(gmp_mul(gmp_abs(gmp_init($a->cents, 10)), 100), 50), gmp_abs(gmp_init($b->cents, 10)), GMP_ROUND_ZERO));
     if ($sign_a * $sign_b < 0) {
         $ret->cents = gmp_strval(gmp_neg(gmp_init($ret->cents, 10)));
     }
     return $ret;
 }