php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #28525 gmp_powm() can't use hexadecimal string modulo
Submitted: 2004-05-26 11:08 UTC Modified: 2004-06-09 16:39 UTC
Votes:1
Avg. Score:4.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: pickett at sumu dot org Assigned:
Status: Closed Package: *Math Functions
PHP Version: 4.3.7RC1 OS:
Private report: No CVE-ID:
 [2004-05-26 11:08 UTC] pickett at sumu dot org
Description:
------------
Fix for bug #27172 broke hexadecimal string modulos for gmp_powm().

Reproduce code:
---------------
var_dump(gmp_powm("0x1", "0x1", "0x1"))

Expected result:
----------------
resource(4) of type (GMP integer)


Actual result:
--------------
bool(false)


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2004-05-26 19:24 UTC] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

Do not pass hex numbers as strings. 
var_dump(gmp_powm(0x1, 0x1, 0x1)); 
 
works fine. 
 [2004-05-26 19:39 UTC] pickett at sumu dot org
I used "0x1" here for brevity.  In real world I use gmp_powm() for diffie-hellman key exchange with vastly larger numbers that can't be represented as normal integers in php.
 [2004-05-28 11:59 UTC] pickett at sumu dot org
Here's a fix

--- php-4.3.7RC1/ext/gmp/gmp.c  2004-02-16 17:13:49.000000000 +0200
+++ php-4.3.7RC1/ext/gmp/gmp.c  2004-05-28 12:56:59.000000000 +0300
@@ -830,8 +830,7 @@
        }
        FETCH_GMP_ZVAL(gmpnum_mod, mod_arg);

-       convert_to_long_ex(mod_arg);
-       if (!Z_LVAL_PP(mod_arg)) {
+       if(mpz_cmp_ui(*gmpnum_mod, 0) == 0) {
                RETURN_FALSE;
        }
 [2004-06-09 16:02 UTC] pickett at sumu dot org
Since I think I failed to explain the problem with just a simple gmp_powm() call, here's the entire diffie hellman implementation:

  $x = "0x98dd1dc9405f6d49b3ede0b8fb59d4db"; // random
  $y = "0x950ba32bc15861f13fe579b29a329ae3"; // random

  $n = "0xFFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD129024E088A67CC74020BBEA63B139B22514A08798E3404DDEF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7EDEE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381FFFFFFFFFFFFFFFF"; // prime (ISAKMP/Oakley group1)
  $g = "0x2"; // generator for $n
  
  $X = gmp_powm($g, $x, $n);
  $Y = gmp_powm($g, $y, $n);

  $keyX = gmp_powm($X, $y, $n);
  $keyY = gmp_powm($Y, $x, $n);

  var_dump(gmp_strval($keyX, 16));
  var_dump(gmp_strval($keyY, 16));

  var_dump(gmp_cmp($keyX, $keyY));

Now, with php 4.3.4 and earlier the above code worked fine, but with 4.3.6 and later it fails (all gmp_powm() calls return false).  There is no way to express $n as a normal php integer, but gmp_powm() still tries to convert it into one just to see if it is zero (and believes it is, as it starts with 0x...).

Using gmp_sgn(*gmpnum_mod) to check if it is zero will work on large numbers, and is probably faster as well since it is a macro that just checks for _mp_size in the gmp mpz structure.

The workaround is simple, just gmp_init() the modulo first, but I believe this still is a bug that should be fixed.
 [2004-06-09 16:39 UTC] iliaa@php.net
This bug has been fixed in CVS.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Fri Apr 18 23:01:58 2014 UTC