public function testInvertm() { $this->assertEquals(gmp_strval(gmp_invert($this->a, $this->a)), $this->math->invertm($this->a, $this->a)); $this->assertEquals(gmp_strval(gmp_invert($this->b, $this->b)), $this->math->invertm($this->b, $this->b)); $this->assertEquals(gmp_strval(gmp_invert($this->c, $this->c)), $this->math->invertm($this->c, $this->c)); $this->assertEquals(0, $this->math->invertm(1, 1)); $o = '2'; $p = '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'; $this->assertEquals('57896044618658097711785492504343953926634992332820282019728792003954417335832', $this->math->invertm($o, $p)); $o = '-207267379875244730201206352791949018434229233557197871725317424106240926035466'; $p = '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'; $this->assertEquals('93736451599995461267424215486556527005103980679329099329644578865571485201981', $this->math->invertm($o, $p)); }
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"); } }
public function testiInvertm() { $math = new BcEngine(); $a = 1234; $b = '1234123412341234123412341234123412412341234213412421341342342'; $c = '0x1234123412341234123412341234123412412341234213412421341342342'; $this->assertEquals(gmp_strval(gmp_invert($a, $a)), $math->invertm($a, $a)); $this->assertEquals(gmp_strval(gmp_invert($b, $b)), $math->invertm($b, $b)); $this->assertEquals(gmp_strval(gmp_invert($c, $c)), $math->invertm($c, $c)); $this->assertEquals(gmp_strval(gmp_invert(15, 14)), $math->invertm(15, 14)); $this->assertEquals(gmp_strval(gmp_invert(-1, 1)), $math->invertm(-1, 1)); $this->assertEquals(0, $math->invertm(1, 1)); $o = '2'; $p = '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'; $this->assertEquals('57896044618658097711785492504343953926634992332820282019728792003954417335832', $math->invertm($o, $p)); $o = '-207267379875244730201206352791949018434229233557197871725317424106240926035466'; $p = '0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f'; $this->assertEquals('93736451599995461267424215486556527005103980679329099329644578865571485201981', $math->invertm($o, $p)); }
/** * verify using gmp extendsions */ function _verifyByGmp($message, $sig, $sigKeys) { $p = $sigKeys['p']; $q = $sigKeys['q']; $g = $sigKeys['g']; $pubKey = $sigKeys['pub_key']; list($r_sig, $s_sig) = explode(":", $sig); $r_sig = base64_decode($r_sig); $s_sig = base64_decode($s_sig); $p = gmp_init($p); $q = gmp_init($q); $g = gmp_init($g); $pubKey = gmp_init($pubKey); $s1 = Security_DSA::_bindecGmp($r_sig); $s2 = Security_DSA::_bindecGmp($s_sig); $w = gmp_invert($s2, $q); $hash_m = gmp_init('0x' . sha1($message)); $u1 = gmp_mod(gmp_mul($hash_m, $w), $q); $u2 = gmp_mod(gmp_mul($s1, $w), $q); $v = gmp_mod(gmp_mod(gmp_mul(gmp_powm($g, $u1, $p), gmp_powm($pubKey, $u2, $p)), $p), $q); return gmp_cmp($v, $s1) == 0; }
public static function double(Point $p1) { if (extension_loaded('gmp') && USE_EXT == 'GMP') { $p = $p1->curve->getPrime(); $a = $p1->curve->getA(); // $inverse = NumberTheory::inverse_mod(gmp_strval(gmp_mul(2, $p1->y)), $p); $inverse = gmp_strval(gmp_invert(gmp_strval(gmp_mul(2, $p1->y)), $p)); $three_x2 = gmp_mul(3, gmp_pow($p1->x, 2)); $l = gmp_strval(gmp_Utils::gmp_mod2(gmp_mul(gmp_add($three_x2, $a), $inverse), $p)); $x3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_pow($l, 2), gmp_mul(2, $p1->x)), $p)); $y3 = gmp_strval(gmp_Utils::gmp_mod2(gmp_sub(gmp_mul($l, gmp_sub($p1->x, $x3)), $p1->y), $p)); if (gmp_cmp(0, $y3) > 0) { $y3 = gmp_strval(gmp_add($p, $y3)); } $p3 = new Point($p1->curve, $x3, $y3); return $p3; } else { throw new ErrorException("Please install GMP"); } }
$ham1 = gmp_init("1001010011", 2); $ham2 = gmp_init("1011111100", 2); echo gmp_hamdist($ham1, $ham2) . "\n"; echo gmp_popcount(gmp_xor($ham1, $ham2)) . "\n"; // gmp_init (although that's probably tested well by now) var_dump($a = gmp_init(123456)); var_dump($b = gmp_init("0xFFFFDEBACDFEDF7200")); // gmp_intval echo gmp_intval(PHP_INT_MAX) . "\n"; echo gmp_intval(gmp_add(PHP_INT_MAX, 1)) . "\n"; echo gmp_intval(gmp_sub(PHP_INT_MAX, 1)) + 1 . "\n"; echo gmp_strval(gmp_add(PHP_INT_MAX, 1)) . "\n"; // gmp_invert echo gmp_invert("5", "10"); // no inverse, outputs nothing, result is FALSE $invert = gmp_invert("5", "11"); echo gmp_strval($invert) . "\n"; // 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");
public function checkSignaturePoints($pubKey, $R, $S, $hash) { $G = $this->G; $pubKeyPts = $this->getPubKeyPointsWithDerPubKey($pubKey); // S^-1* hash * G + S^-1 * R * Qa // S^-1* hash $exp1 = gmp_strval(gmp_mul(gmp_invert(gmp_init($S, 16), $this->n), gmp_init($hash, 16)), 16); // S^-1* hash * G $exp1Pt = $this->mulPoint($exp1, $G); // S^-1 * R $exp2 = gmp_strval(gmp_mul(gmp_invert(gmp_init($S, 16), $this->n), gmp_init($R, 16)), 16); // S^-1 * R * Qa $pubKeyPts['x'] = gmp_init($pubKeyPts['x'], 16); $pubKeyPts['y'] = gmp_init($pubKeyPts['y'], 16); $exp2Pt = $this->mulPoint($exp2, $pubKeyPts); $resultingPt = $this->addPoints($exp1Pt, $exp2Pt); $xRes = gmp_strval($resultingPt['x'], 16); while (strlen($xRes) < 64) { $xRes = '0' . $xRes; } if (strtoupper($xRes) == strtoupper($R)) { return true; } else { return false; } }
public function multiplicativeInverse($number, $modulus) { return gmp_invert($number, $modulus); }
/** * Calculates modular inverses. * * Say you have (30 mod 17 * x mod 17) mod 17 == 1. x can be found using modular inverses. * * Here's an example: * <code> * <?php * include 'Math/BigInteger.php'; * * $a = new Math_BigInteger(30); * $b = new Math_BigInteger(17); * * $c = $a->modInverse($b); * echo $c->toString(); // outputs 4 * * echo "\r\n"; * * $d = $a->multiply($c); * list(, $d) = $d->divide($b); * echo $d; // outputs 1 (as per the definition of modular inverse) * ?> * </code> * * @param Math_BigInteger $n * @return Math_BigInteger|false * @access public * @internal See {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information. */ function modInverse($n) { switch (MATH_BIGINTEGER_MODE) { case MATH_BIGINTEGER_MODE_GMP: $temp = new Math_BigInteger(); $temp->value = gmp_invert($this->value, $n->value); return $temp->value === false ? false : $this->_normalize($temp); } static $zero, $one; if (!isset($zero)) { $zero = new Math_BigInteger(); $one = new Math_BigInteger(1); } // $x mod -$n == $x mod $n. $n = $n->abs(); if ($this->compare($zero) < 0) { $temp = $this->abs(); $temp = $temp->modInverse($n); return $this->_normalize($n->subtract($temp)); } extract($this->extendedGCD($n)); if (!$gcd->equals($one)) { return false; } $x = $x->compare($zero) < 0 ? $x->add($n) : $x; return $this->compare($zero) < 0 ? $this->_normalize($n->subtract($x)) : $this->_normalize($x); }
<?php var_dump(gmp_strval(gmp_invert(123123, 5467624))); var_dump(gmp_strval(gmp_invert(123123, "3333334345467624"))); var_dump(gmp_strval(gmp_invert("12312323213123123", 7624))); var_dump(gmp_strval(gmp_invert(444, 0))); var_dump(gmp_strval(gmp_invert(0, 28347))); var_dump(gmp_strval(gmp_invert(-12, 456456))); var_dump(gmp_strval(gmp_invert(234234, -435345))); $n = gmp_init("349827349623423452345"); $n1 = gmp_init("3498273496234234523451"); var_dump(gmp_strval(gmp_invert($n, $n1))); var_dump(gmp_strval(gmp_invert($n1, $n))); var_dump(gmp_invert($n1, $n, 10)); var_dump(gmp_invert($n1)); var_dump(gmp_invert(array(), 1)); var_dump(gmp_invert(1, array())); var_dump(gmp_invert(array(), array())); echo "Done\n";
/** * Calculates modular inverses. * * @param \Jose\Util\BigInteger $n * * @return \Jose\Util\BigInteger */ public function modInverse(BigInteger $n) { $value = gmp_invert($this->value, $n->value); Assertion::isInstanceOf($value, \GMP::class); return self::createFromGMPResource($value); }
foreach ($lines as $line) { if (!strstr($line, "=")) { continue; } list($lk, $lv) = explode("=", trim($line)); $vars[trim($lk)] = trim($lv); } $n = $vars["n"]; $p = $vars["p"]; $q = $vars["q"]; $e = $vars["e"]; $d = $vars["d"]; $gmp_n = gmp_init($n, 16); $gmp_p = gmp_init($p, 16); $gmp_q = gmp_init($q, 16); $gmp_e = gmp_init($e, 16); $gmp_d = gmp_init($d, 16); if (gmp_cmp($gmp_p, $gmp_q) < 0) { $tmp = $gmp_p; $gmp_p = $gmp_q; $gmp_q = $tmp; } $gmp_p1 = gmp_sub($gmp_p, 1); $gmp_q1 = gmp_sub($gmp_q, 1); $gmp_dp = gmp_mod($gmp_d, $gmp_p1); $gmp_dq = gmp_mod($gmp_d, $gmp_q1); $gmp_qi = gmp_invert($gmp_q, $gmp_p); printf("n =%s\ne =%s\nd =%s\np =%s\nq =%s\ndp=%s\ndq=%s\nqi=%s\n", gmp_strval($gmp_n, 16), gmp_strval($gmp_e, 16), gmp_strval($gmp_d, 16), gmp_strval($gmp_p, 16), gmp_strval($gmp_q, 16), gmp_strval($gmp_dp, 16), gmp_strval($gmp_dq, 16), gmp_strval($gmp_qi, 16)); $der = sprintf("3082 %04x\n 0201 00\n 02%02x %s\n 02%02x %s\n 02%02x %s\n 02%02x %s\n 02%02x %s\n 02%02x %s\n 02%02x %s\n 02%02x %s\n", 19 + bytelen($gmp_n) + bytelen($gmp_e) + bytelen($gmp_d) + bytelen($gmp_p) + bytelen($gmp_q) + bytelen($gmp_dp) + bytelen($gmp_dq) + bytelen($gmp_qi), bytelen($gmp_n), bytepad($gmp_n), bytelen($gmp_e), bytepad($gmp_e), bytelen($gmp_d), bytepad($gmp_d), bytelen($gmp_p), bytepad($gmp_p), bytelen($gmp_q), bytepad($gmp_q), bytelen($gmp_dp), bytepad($gmp_dp), bytelen($gmp_dq), bytepad($gmp_dq), bytelen($gmp_qi), bytepad($gmp_qi)); echo "DER:\n{$der}\n"; echo "PEM:\n-----BEGIN RSA PRIVATE KEY-----\n" . hex_to_base64($der) . "\n-----END RSA PRIVATE KEY-----\n";
/** * GMP's inverse modulo function, where ax = 1(mod p). * * @param string $a The number to inverse modulo. * @param string $b The modulus. * @return string */ public function inv($a, $b) { return gmp_strval(gmp_invert($a, $b)); }
function _dsa_verify_gmp($message, $sig, $key) { list($r_sig, $s_sig) = explode(":", $sig); $r_sig = base64_decode($r_sig); $s_sig = base64_decode($s_sig); foreach ($key as $i => $v) { $key[$i] = gmp_init($v); } $s1 = gmp_init($this->_gmp_bindec($r_sig)); $s2 = gmp_init($this->_gmp_bindec($s_sig)); $w = gmp_invert($s2, $key['q']); $hash_m = gmp_init('0x' . sha1($message)); $u1 = gmp_mod(gmp_mul($hash_m, $w), $key['q']); $u2 = gmp_mod(gmp_mul($s1, $w), $key['q']); $v = gmp_mod(gmp_mod(gmp_mul(gmp_powm($key['g'], $u1, $key['p']), gmp_powm($key['pub_key'], $u2, $key['p'])), $key['p']), $key['q']); if (gmp_cmp($v, $s1) == 0) { return true; } else { return false; } }
/** * Calculates modular inverses. * * Here's a quick 'n dirty example: * <code> * <?php * include('Math/BigInteger.php'); * * $a = new Math_BigInteger(30); * $b = new Math_BigInteger(17); * * $c = $a->modInverse($b); * * echo $c->toString(); // outputs 4 * ?> * </code> * * @param Math_BigInteger $n * @return mixed false, if no modular inverse exists, Math_BigInteger, otherwise. * @access public * @internal Calculates the modular inverse of $this mod $n using the binary xGCD algorithim described in * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=19 HAC 14.61}. As the text above 14.61 notes, * the more traditional algorithim requires "relatively costly multiple-precision divisions". See * {@link http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf#page=21 HAC 14.64} for more information. */ function modInverse($n) { switch (MATH_BIGINTEGER_MODE) { case MATH_BIGINTEGER_MODE_GMP: $temp = new Math_BigInteger(); $temp->value = gmp_invert($this->value, $n->value); return $temp->value === false ? false : $temp; case MATH_BIGINTEGER_MODE_BCMATH: // it might be faster to use the binary xGCD algorithim here, as well, but (1) that algorithim works // best when the base is a power of 2 and (2) i don't think it'd make much difference, anyway. as is, // the basic extended euclidean algorithim is what we're using. // if $x is less than 0, the first character of $x is a '-', so we'll remove it. we can do this because // $x mod $n == $x mod -$n. $n = bccomp($n->value, '0') < 0 ? substr($n->value, 1) : $n->value; if (bccomp($this->value, '0') < 0) { $negated_this = new Math_BigInteger(); $negated_this->value = substr($this->value, 1); $temp = $negated_this->modInverse(new Math_BigInteger($n)); if ($temp === false) { return false; } $temp->value = bcsub($n, $temp->value); return $temp; } $u = $this->value; $v = $n; $a = '1'; $c = '0'; while (true) { $q = bcdiv($u, $v); $temp = $u; $u = $v; $v = bcsub($temp, bcmul($v, $q)); if (bccomp($v, '0') == 0) { break; } $temp = $a; $a = $c; $c = bcsub($temp, bcmul($c, $q)); } $temp = new Math_BigInteger(); $temp->value = bccomp($c, '0') < 0 ? bcadd($c, $n) : $c; // $u contains the gcd of $this and $n return bccomp($u, '1') == 0 ? $temp : false; } // if $this and $n are even, return false. if (!($this->value[0] & 1) && !($n->value[0] & 1)) { return false; } $n = $n->_copy(); $n->is_negative = false; if ($this->compare(new Math_BigInteger()) < 0) { // is_negative is currently true. since we need it to be false, we'll just set it to false, temporarily, // and reset it as true, later. $this->is_negative = false; $temp = $this->modInverse($n); if ($temp === false) { return false; } $temp = $n->subtract($temp); $this->is_negative = true; return $temp; } $u = $n->_copy(); $x = $this; //list(, $x) = $this->divide($n); $v = $x->_copy(); $a = new Math_BigInteger(); $b = new Math_BigInteger(); $c = new Math_BigInteger(); $d = new Math_BigInteger(); $a->value = $d->value = array(1); while (!empty($u->value)) { while (!($u->value[0] & 1)) { $u->_rshift(1); if ($a->value[0] & 1 || $b->value[0] & 1) { $a = $a->add($x); $b = $b->subtract($n); } $a->_rshift(1); $b->_rshift(1); } while (!($v->value[0] & 1)) { $v->_rshift(1); if ($c->value[0] & 1 || $d->value[0] & 1) { $c = $c->add($x); $d = $d->subtract($n); } $c->_rshift(1); $d->_rshift(1); } if ($u->compare($v) >= 0) { $u = $u->subtract($v); $a = $a->subtract($c); $b = $b->subtract($d); } else { $v = $v->subtract($u); $c = $c->subtract($a); $d = $d->subtract($b); } $u->_normalize(); } // at this point, $v == gcd($this, $n). if it's not equal to 1, no modular inverse exists. if ($v->value != array(1)) { return false; } $d = $d->compare(new Math_BigInteger()) < 0 ? $d->add($n) : $d; return $this->is_negative ? $n->subtract($d) : $d; }
/** * Computes the inverse of $number in modulo $modulus. * * @param resource $number The number for which to calculate the inverse * @param resource $modulus The modulo value in which the inverse is calculated * @return resource */ public function invert($number, $modulus) { return gmp_invert($number, $modulus); }
/** * Finds inverse number $inv for $num by modulus $mod, such as: * $inv * $num = 1 (mod $mod) * * @param gmp resource $num * @param gmp resource $mod * @return gmp resource * @access public */ function invmod($num, $mod) { return gmp_invert($num, $mod); }
public static function inverse_mod($a, $m) { if (extension_loaded('gmp') && USE_EXT == 'GMP') { $inverse = gmp_strval(gmp_invert($a, $m)); return $inverse; } elseif (extension_loaded('bcmath') && USE_EXT == 'BCMATH') { while (bccomp($a, 0) == -1) { $a = bcadd($m, $a); } while (bccomp($m, $a) == -1) { $a = bcmod($a, $m); } $c = $a; $d = $m; $uc = 1; $vc = 0; $ud = 0; $vd = 1; while (bccomp($c, 0) != 0) { $temp1 = $c; $q = bcdiv($d, $c, 0); $c = bcmod($d, $c); $d = $temp1; $temp2 = $uc; $temp3 = $vc; $uc = bcsub($ud, bcmul($q, $uc)); $vc = bcsub($vd, bcmul($q, $vc)); $ud = $temp2; $vd = $temp3; } $result = ''; if (bccomp($d, 1) == 0) { if (bccomp($ud, 0) == 1) { $result = $ud; } else { $result = bcadd($ud, $m); } } else { throw new ErrorException("ERROR: {$a} and {$m} are NOT relatively prime."); } return $result; } else { throw new ErrorException("Please install BCMATH or GMP"); } }
public static function double(Point $p1) { $p = $p1->curve->prime; $a = $p1->curve->a; $inverse = gmp_invert(gmp_mul(2, $p1->y), $p); $three_x2 = gmp_mul(3, gmp_pow($p1->x, 2)); $l = gmp_mod(gmp_mul(gmp_add($three_x2, $a), $inverse), $p); $x3 = gmp_mod(gmp_sub(gmp_pow($l, 2), gmp_mul(2, $p1->x)), $p); $y3 = gmp_mod(gmp_sub(gmp_mul($l, gmp_sub($p1->x, $x3)), $p1->y), $p); if (gmp_cmp(0, $y3) > 0) { $y3 = gmp_add($p, $y3); } return new Point($p1->curve, $x3, $y3); }
/** * {@inheritDoc} * @see \Mdanter\Ecc\MathAdapterInterface::inverseMod() */ public function inverseMod($a, $m) { return gmp_strval(gmp_invert(gmp_init($a, 10), gmp_init($m, 10))); }