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; }
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); }
// 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"));
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); }
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; } }
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); }
<?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";
/** * 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()))); }
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)); }
/** * Negates the number * * @return \Chippyash\Type\Number\GMPIntType Fluent Interface */ public function negate() { $this->value = gmp_neg($this->value); return $this; }
/** * @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); }
/** * Negates the value. * * @return BigInteger */ public function negate() : BigInteger { $calculatedValue = gmp_neg($this->value); return $this->assignValue($calculatedValue); }
public function size() { if( !$this->valid ) { return 0; } return gmp_intval( gmp_add( $this->net_broadcast_long, gmp_neg( $this->net_addr_long ))); }
/** * 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; }