Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ PHP NEWS
declares a default value for the attribute). (iliaal)

- GMP:
. Added gmp_powm_sec(). (Weilin Du)
. Fixed GMP power and shift operators to reject GMP right operands outside
the unsigned long range instead of silently truncating them. (Weilin Du)
. Fixed GMP integer string parsing to reject strings containing NUL bytes
Expand Down
7 changes: 7 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,10 @@ PHP 8.6 UPGRADE NOTES
- Fileinfo:
. finfo_file() now works with remote streams.

- GMP:
. Added gmp_powm_sec() for side-channel quiet modular exponentiation.
Requires GNU MP 5.0.0 or later.

- Intl:
. Added Locale::getDisplayKeyword() and Locale::getDisplayKeywordValue(),
with the alias of locale_get_display_keyword() and
Expand Down Expand Up @@ -406,6 +410,9 @@ PHP 8.6 UPGRADE NOTES
6. New Functions
========================================

- GMP:
. gmp_powm_sec()

- Intl:
. grapheme_strrev()
RFC: https://wiki.php.net/rfc/grapheme_strrev
Expand Down
1 change: 1 addition & 0 deletions ext/gmp/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ if test "$PHP_GMP" != "no"; then
LIBS="$LIBS $GMP_LIBS"
gmp_check=no
AC_CHECK_HEADER([gmp.h], [AC_CHECK_FUNC([__gmpz_rootrem], [gmp_check=yes])])
AC_CHECK_FUNCS([__gmpz_powm_sec])
CFLAGS=$CFLAGS_SAVED
LIBS=$LIBS_SAVED

Expand Down
3 changes: 3 additions & 0 deletions ext/gmp/config.w32
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ ARG_WITH("gmp", "Include GNU MP support.", "no");
if (PHP_GMP != "no") {
if (CHECK_LIB("mpir_a.lib", "gmp", PHP_GMP) &&
CHECK_HEADER("gmp.h", "CFLAGS_GMP", PHP_GMP + ";" + PHP_PHP_BUILD + "\\include\\mpir")) {
if (GREP_HEADER("gmp.h", "mpz_powm_sec", PHP_GMP + ";" + PHP_PHP_BUILD + "\\include\\mpir")) {
AC_DEFINE('HAVE___GMPZ_POWM_SEC', 1, "Define to 1 if GMP has the 'mpz_powm_sec' function.");
}
EXTENSION("gmp", "gmp.c", null, "/DZEND_ENABLE_STATIC_TSRMLS_CACHE=1");
PHP_INSTALL_HEADERS("ext/gmp", "php_gmp_int.h");
AC_DEFINE('HAVE_GMP', 1, "Define to 1 if the PHP extension 'gmp' is available.");
Expand Down
33 changes: 33 additions & 0 deletions ext/gmp/gmp.c
Original file line number Diff line number Diff line change
Expand Up @@ -1189,6 +1189,39 @@ ZEND_FUNCTION(gmp_powm)
}
/* }}} */

#ifdef HAVE___GMPZ_POWM_SEC
/* {{{ Raise base to power exp and take result modulo mod using a side-channel quiet algorithm */
ZEND_FUNCTION(gmp_powm_sec)
{
mpz_ptr gmpnum_base, gmpnum_exp, gmpnum_mod, gmpnum_result;

ZEND_PARSE_PARAMETERS_START(3, 3)
GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_base)
GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_exp)
GMP_Z_PARAM_INTO_MPZ_PTR(gmpnum_mod)
ZEND_PARSE_PARAMETERS_END();

if (mpz_sgn(gmpnum_exp) <= 0) {
zend_argument_value_error(2, "must be greater than 0");
RETURN_THROWS();
}

if (!mpz_cmp_ui(gmpnum_mod, 0)) {
zend_argument_error(zend_ce_division_by_zero_error, 3, "Modulo by zero");
RETURN_THROWS();
}

if (!mpz_odd_p(gmpnum_mod)) {
zend_argument_value_error(3, "must be odd");
RETURN_THROWS();
}

INIT_GMP_RETVAL(gmpnum_result);
mpz_powm_sec(gmpnum_result, gmpnum_base, gmpnum_exp, gmpnum_mod);
}
/* }}} */
#endif

/* {{{ Takes integer part of square root of a */
ZEND_FUNCTION(gmp_sqrt)
{
Expand Down
4 changes: 4 additions & 0 deletions ext/gmp/gmp.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ function gmp_pow(GMP|int|string $num, int $exponent): GMP {}

function gmp_powm(GMP|int|string $num, GMP|int|string $exponent, GMP|int|string $modulus): GMP {}

#ifdef HAVE___GMPZ_POWM_SEC
function gmp_powm_sec(GMP|int|string $num, GMP|int|string $exponent, GMP|int|string $modulus): GMP {}
#endif

function gmp_perfect_square(GMP|int|string $num): bool {}

function gmp_perfect_power(GMP|int|string $num): bool {}
Expand Down
16 changes: 15 additions & 1 deletion ext/gmp/gmp_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions ext/gmp/tests/bug80560.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ $functions2 = [
$functions3 = [
'gmp_powm',
];
if (function_exists('gmp_powm_sec')) {
$functions3[] = 'gmp_powm_sec';
}

echo 'Explicit base with gmp_init:', \PHP_EOL;
echo 'Hexadecimal', \PHP_EOL;
Expand Down
46 changes: 46 additions & 0 deletions ext/gmp/tests/gmp_powm_sec.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
--TEST--
gmp_powm_sec()
--EXTENSIONS--
gmp
--SKIPIF--
<?php
if (!function_exists('gmp_powm_sec')) {
die('skip gmp_powm_sec() is not available');
}
?>
--FILE--
<?php

var_dump(gmp_strval(gmp_powm_sec(4, 13, 497)));
var_dump(gmp_strval(gmp_powm_sec(gmp_init(7), gmp_init(3), gmp_init(13))));

foreach ([0, -1] as $exp) {
try {
var_dump(gmp_powm_sec(4, $exp, 497));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}
}

try {
var_dump(gmp_powm_sec(4, 13, 0));
} catch (\DivisionByZeroError $e) {
echo $e->getMessage(), \PHP_EOL;
}

try {
var_dump(gmp_powm_sec(4, 13, 496));
} catch (\ValueError $e) {
echo $e->getMessage(), \PHP_EOL;
}

echo "Done\n";
?>
--EXPECT--
string(3) "445"
string(1) "5"
gmp_powm_sec(): Argument #2 ($exponent) must be greater than 0
gmp_powm_sec(): Argument #2 ($exponent) must be greater than 0
gmp_powm_sec(): Argument #3 ($modulus) Modulo by zero
gmp_powm_sec(): Argument #3 ($modulus) must be odd
Done
Loading