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: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: pickett at sumu dot org
New email:
PHP Version: OS:

 

 [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

Pull Requests

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-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 02:01:28 2024 UTC