hash() dies with SIGFPE when passing r or p

Create issue
Issue #6 resolved
Matti Niemenmaa created an issue

Specifying the 'r' or 'p' parameters to hash() causes a floating point exception (SIGFPE) on my system. For example: {{{ $ python2 Python 2.7.3 (default, Apr 24 2012, 00:00:54) [GCC 4.7.0 20120414 (prerelease)] on linux2 Type "help", "copyright", "credits" or "license" for more information.

import scrypt scrypt.hash('foo', 'bar', r=10) zsh: floating point exception python2 }}} I guess this is explained by the comment on line 157 in scrypt2.c, here: https://bitbucket.org/mhallin/py-scrypt/src/6f4a8903fd02/src/scrypt2.c#cl-157 --- I'm on a 64-bit system so unsigned long is uint64_t, not uint32_t.

On most platforms nowadays "unsigned int" ('I' in the format string) is uint32_t, so that would be the safer choice. Probably the safest option would be to keep the format string, but turn N into an "unsigned long long" and "r" and "p" into "unsigned long", and then cast them to uint64_t and uint32_t as needed. That way the format string exactly matches the variable types.

As an aside: couldn't the output buffer length also be a parameter to hash()?

Comments (5)

  1. Kelvin Wong

    The operation of the hash function is unpredictable on CentOS 6 x86_64. Sometimes it returns a paramerror, sometimes a bad hash and sometimes it just crashes the interpreter.

    $ uname -a
    Linux example.com 2.6.32-220.17.1.el6.x86_64 #1 SMP Wed May 16 00:01:37 BST 2012 x86_64 x86_64 x86_64 GNU/Linux
    $ python3.2 -c "import scrypt; scrypt.hash('pleaseletmein', 'SodiumChloride', N=32768, r=16, p=4)"
    Traceback (most recent call last):
      File "<string>", line 1, in <module>
    scrypt.error: hash parameters are wrong (r*p should be < 2**30, and N should be a power of two > 1)

    It seems to work fine on 32-bit systems though (MacOS and CentOS).

  2. Kelvin Wong
    • changed status to open

    I have a working solution for this on my fork


    I'm going to do more testing, but it seems to work on MacOS 10.5.8 32-bit, CentOS 6 i686 and x86_64.

    Python 3.2.3 (default, Jun 19 2012, 16:40:33) 
    [GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import scrypt as s
    >>> import binascii as b
    >>> b.b2a_hex(s.hash("", "", N=16, r=1, p=1))
    >>> b.b2a_hex(s.hash("password", "NaCl", N=1024, r=8, p=16))
    >>> b.b2a_hex(s.hash("pleaseletmein", "SodiumChloride", N=16384, r=8, p=1))
    >>> b.b2a_hex(s.hash("pleaseletmein", "SodiumChloride", N=32768, r=16, p=4))
  3. Kelvin Wong

    couldn't the output buffer length also be a parameter to hash()?

    @deewiant Could you open another issue as an Enhancement for your idea about adding a parameter for output buffer length?

  4. Log in to comment