scrypt-0.8.0/0000755000076500000240000000000012767242550013624 5ustar mhallinstaff00000000000000scrypt-0.8.0/MANIFEST.in0000644000076500000240000000037612767242505015370 0ustar mhallinstaff00000000000000recursive-include scrypt-1.2.0 *.h include README.rst include src/*.c include tests/__init__.py include tests/ciphertexts.csv include tests/hashvectors.csv include tests/test_scrypt.py include tests/test_scrypt_py2x.py include tests/test_scrypt_py3x.py scrypt-0.8.0/PKG-INFO0000644000076500000240000001361212767242550014724 0ustar mhallinstaff00000000000000Metadata-Version: 1.1 Name: scrypt Version: 0.8.0 Summary: Bindings for the scrypt key derivation function library Home-page: http://bitbucket.org/mhallin/py-scrypt Author: Magnus Hallin Author-email: mhallin@gmail.com License: 2-clause BSD Description: ========================= Python scrypt_ bindings ========================= This is a set of Python_ bindings for the scrypt_ key derivation function. Scrypt is useful when encrypting password as it is possible to specify a *minimum* amount of time to use when encrypting and decrypting. If, for example, a password takes 0.05 seconds to verify, a user won't notice the slight delay when signing in, but doing a brute force search of several billion passwords will take a considerable amount of time. This is in contrast to more traditional hash functions such as MD5 or the SHA family which can be implemented extremely fast on cheap hardware. Installation ============ You can install py-scrypt from this repository if you want the latest but possibly non-compiling version:: $ hg clone http://bitbucket.org/mhallin/py-scrypt $ cd py-scrypt $ python setup.py build Become superuser (or use virtualenv): # python setup.py install Run tests after install: $ python setup.py test Or you can install the latest release from PyPi:: $ pip install scrypt If you want py-scrypt for your Python 3 environment, just run the above commands with your Python 3 interpreter. Py-scrypt supports both Python 2 and 3. From version 0.6.0 (not available on PyPi yet), py-scrypt supports PyPy as well. Usage ===== Fore encryption/decryption, the library exports two functions ``encrypt`` and ``decrypt``:: >>> import scrypt >>> data = scrypt.encrypt('a secret message', 'password', maxtime=0.1) # This will take at least 0.1 seconds >>> data[:20] 'scrypt\x00\r\x00\x00\x00\x08\x00\x00\x00\x01RX9H' >>> scrypt.decrypt(data, 'password', maxtime=0.1) # This will also take at least 0.1 seconds 'a secret message' >>> scrypt.decrypt(data, 'password', maxtime=0.05) # scrypt won't be able to decrypt this data fast enough Traceback (most recent call last): File "", line 1, in scrypt.error: decrypting file would take too long >>> scrypt.decrypt(data, 'wrong password', maxtime=0.1) # scrypt will throw an exception if the password is incorrect Traceback (most recent call last): File "", line 1, in scrypt.error: password is incorrect From these, one can make a simple password verifier using the following functions:: def hash_password(password, maxtime=0.5, datalength=64): return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime) def verify_password(hashed_password, guessed_password, maxtime=0.5): try: scrypt.decrypt(hashed_password, guessed_password, maxtime) return True except scrypt.error: return False But, if you want output that is deterministic and constant in size, you can use the ``hash`` function:: >>> import scrypt >>> h1 = scrypt.hash('password', 'random salt') >>> len(h1) # The hash will be 64 bytes by default, but is overridable. 64 >>> h1[:10] '\xfe\x87\xf3hS\tUo\xcd\xc8' >>> h2 = scrypt.hash('password', 'random salt') >>> h1 == h2 # The hash function is deterministic True Acknowledgements ================ Scrypt_ was created by Colin Percival and is licensed as 2-clause BSD. Since scrypt does not normally build as a shared library, I have included the source for the currently latest version of the library in this repository. When a new version arrives, I will update these sources. `Kelvin Wong`_ on Bitbucket provided changes to make the library available on Mac OS X 10.6 and earlier, as well as changes to make the library work more like the command-line version of scrypt by default. Kelvin also contributed with the unit tests, lots of cross platform testing and work on the ``hash`` function. Burstaholic_ on Bitbucket provided the necessary changes to make the library build on Windows. The `python-appveyor-demo`_ repository for setting up automated Windows builds for a multitude of Python versions. License ======= This library is licensed under the same license as scrypt; 2-clause BSD. .. _scrypt: http://www.tarsnap.com/scrypt.html .. _Python: http://python.org .. _Burstaholic: https://bitbucket.org/Burstaholic .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Security :: Cryptography Classifier: Topic :: Software Development :: Libraries scrypt-0.8.0/README.rst0000644000076500000240000001036412767226274015324 0ustar mhallinstaff00000000000000========================= Python scrypt_ bindings ========================= This is a set of Python_ bindings for the scrypt_ key derivation function. Scrypt is useful when encrypting password as it is possible to specify a *minimum* amount of time to use when encrypting and decrypting. If, for example, a password takes 0.05 seconds to verify, a user won't notice the slight delay when signing in, but doing a brute force search of several billion passwords will take a considerable amount of time. This is in contrast to more traditional hash functions such as MD5 or the SHA family which can be implemented extremely fast on cheap hardware. Installation ============ You can install py-scrypt from this repository if you want the latest but possibly non-compiling version:: $ hg clone http://bitbucket.org/mhallin/py-scrypt $ cd py-scrypt $ python setup.py build Become superuser (or use virtualenv): # python setup.py install Run tests after install: $ python setup.py test Or you can install the latest release from PyPi:: $ pip install scrypt If you want py-scrypt for your Python 3 environment, just run the above commands with your Python 3 interpreter. Py-scrypt supports both Python 2 and 3. From version 0.6.0 (not available on PyPi yet), py-scrypt supports PyPy as well. Usage ===== Fore encryption/decryption, the library exports two functions ``encrypt`` and ``decrypt``:: >>> import scrypt >>> data = scrypt.encrypt('a secret message', 'password', maxtime=0.1) # This will take at least 0.1 seconds >>> data[:20] 'scrypt\x00\r\x00\x00\x00\x08\x00\x00\x00\x01RX9H' >>> scrypt.decrypt(data, 'password', maxtime=0.1) # This will also take at least 0.1 seconds 'a secret message' >>> scrypt.decrypt(data, 'password', maxtime=0.05) # scrypt won't be able to decrypt this data fast enough Traceback (most recent call last): File "", line 1, in scrypt.error: decrypting file would take too long >>> scrypt.decrypt(data, 'wrong password', maxtime=0.1) # scrypt will throw an exception if the password is incorrect Traceback (most recent call last): File "", line 1, in scrypt.error: password is incorrect From these, one can make a simple password verifier using the following functions:: def hash_password(password, maxtime=0.5, datalength=64): return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime) def verify_password(hashed_password, guessed_password, maxtime=0.5): try: scrypt.decrypt(hashed_password, guessed_password, maxtime) return True except scrypt.error: return False But, if you want output that is deterministic and constant in size, you can use the ``hash`` function:: >>> import scrypt >>> h1 = scrypt.hash('password', 'random salt') >>> len(h1) # The hash will be 64 bytes by default, but is overridable. 64 >>> h1[:10] '\xfe\x87\xf3hS\tUo\xcd\xc8' >>> h2 = scrypt.hash('password', 'random salt') >>> h1 == h2 # The hash function is deterministic True Acknowledgements ================ Scrypt_ was created by Colin Percival and is licensed as 2-clause BSD. Since scrypt does not normally build as a shared library, I have included the source for the currently latest version of the library in this repository. When a new version arrives, I will update these sources. `Kelvin Wong`_ on Bitbucket provided changes to make the library available on Mac OS X 10.6 and earlier, as well as changes to make the library work more like the command-line version of scrypt by default. Kelvin also contributed with the unit tests, lots of cross platform testing and work on the ``hash`` function. Burstaholic_ on Bitbucket provided the necessary changes to make the library build on Windows. The `python-appveyor-demo`_ repository for setting up automated Windows builds for a multitude of Python versions. License ======= This library is licensed under the same license as scrypt; 2-clause BSD. .. _scrypt: http://www.tarsnap.com/scrypt.html .. _Python: http://python.org .. _Burstaholic: https://bitbucket.org/Burstaholic .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo scrypt-0.8.0/scrypt-1.2.0/0000755000076500000240000000000012767242550015604 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/config.h0000644000076500000240000000556112767232251017226 0ustar mhallinstaff00000000000000/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Define to 1 if you have the `clock_gettime' function. */ /* #undef HAVE_CLOCK_GETTIME */ /* Define to 1 if you have the declaration of `be64enc', and to 0 if you don't. */ #define HAVE_DECL_BE64ENC 0 /* Define to 1 if you have the header file. */ #define HAVE_ERR_H 1 /* Define to 1 if you have the header file. */ #define HAVE_INTTYPES_H 1 /* Define to 1 if you have the `rt' library (-lrt). */ /* #undef HAVE_LIBRT */ /* Define to 1 if you have the header file. */ #define HAVE_MEMORY_H 1 /* Define to 1 if you have the `posix_memalign' function. */ /* #undef HAVE_POSIX_MEMALIGN */ /* Define to 1 if you have the header file. */ #define HAVE_STDINT_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STDLIB_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRINGS_H 1 /* Define to 1 if you have the header file. */ #define HAVE_STRING_H 1 /* Define to 1 if the system has the type `struct sysinfo'. */ /* #undef HAVE_STRUCT_SYSINFO */ /* Define to 1 if `mem_unit' is member of `struct sysinfo'. */ /* #undef HAVE_STRUCT_SYSINFO_MEM_UNIT */ /* Define to 1 if `totalram' is member of `struct sysinfo'. */ /* #undef HAVE_STRUCT_SYSINFO_TOTALRAM */ /* Define to 1 if the OS has a hw.usermem sysctl */ /* #undef HAVE_SYSCTL_HW_USERMEM */ /* Define to 1 if you have the `sysinfo' function. */ /* #undef HAVE_SYSINFO */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_ENDIAN_H */ /* Define to 1 if you have the header file. */ /* #define HAVE_SYS_PARAM_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_STAT_H 1 /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_SYSINFO_H */ /* Define to 1 if you have the header file. */ #define HAVE_SYS_TYPES_H 1 /* Define to 1 if you have the header file. */ #define HAVE_UNISTD_H 1 /* Name of package */ #define PACKAGE "scrypt" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "" /* Define to the full name of this package. */ #define PACKAGE_NAME "scrypt" /* Define to the full name and version of this package. */ #define PACKAGE_STRING "scrypt 1.2.0" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "scrypt" /* Define to the version of this package. */ #define PACKAGE_VERSION "1.2.0" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1.2.0" /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ /* Define for large files, on AIX-style hosts. */ /* #undef _LARGE_FILES */ scrypt-0.8.0/scrypt-1.2.0/lib/0000755000076500000240000000000012767242550016352 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/lib/crypto/0000755000076500000240000000000012767242550017672 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/lib/crypto/crypto_scrypt.c0000644000076500000240000001555512767233636023002 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #include "scrypt_platform.h" #include #ifndef _WIN32 #include #endif #include #include #include #include #include "cpusupport.h" #include "sha256.h" #include "warnp.h" #include "crypto_scrypt_smix.h" #include "crypto_scrypt_smix_sse2.h" #include "crypto_scrypt.h" static void (*smix_func)(uint8_t *, size_t, uint64_t, void *, void *) = NULL; /** * _crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen, smix): * Perform the requested scrypt computation, using ${smix} as the smix routine. */ static int _crypto_scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p, uint8_t * buf, size_t buflen, void (*smix)(uint8_t *, size_t, uint64_t, void *, void *)) { void * B0, * V0, * XY0; uint8_t * B; uint32_t * V; uint32_t * XY; size_t r = _r, p = _p; uint32_t i; /* Sanity-check parameters. */ #if SIZE_MAX > UINT32_MAX if (buflen > (((uint64_t)(1) << 32) - 1) * 32) { errno = EFBIG; goto err0; } #endif if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) { errno = EFBIG; goto err0; } if (((N & (N - 1)) != 0) || (N < 2)) { errno = EINVAL; goto err0; } if ((r > SIZE_MAX / 128 / p) || #if SIZE_MAX / 256 <= UINT32_MAX (r > (SIZE_MAX - 64) / 256) || #endif (N > SIZE_MAX / 128 / r)) { errno = ENOMEM; goto err0; } /* Allocate memory. */ #ifdef HAVE_POSIX_MEMALIGN if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0) goto err0; B = (uint8_t *)(B0); if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0) goto err1; XY = (uint32_t *)(XY0); #if !defined(MAP_ANON) || !defined(HAVE_MMAP) if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0) goto err2; V = (uint32_t *)(V0); #endif #else if ((B0 = malloc(128 * r * p + 63)) == NULL) goto err0; B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63)); if ((XY0 = malloc(256 * r + 64 + 63)) == NULL) goto err1; XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63)); #if !defined(MAP_ANON) || !defined(HAVE_MMAP) if ((V0 = malloc(128 * r * N + 63)) == NULL) goto err2; V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); #endif #endif #if defined(MAP_ANON) && defined(HAVE_MMAP) if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE, #ifdef MAP_NOCORE MAP_ANON | MAP_PRIVATE | MAP_NOCORE, #else MAP_ANON | MAP_PRIVATE, #endif -1, 0)) == MAP_FAILED) goto err2; V = (uint32_t *)(V0); #endif /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */ PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r); /* 2: for i = 0 to p - 1 do */ for (i = 0; i < p; i++) { /* 3: B_i <-- MF(B_i, N) */ (smix)(&B[i * 128 * r], r, N, V, XY); } /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */ PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); /* Free memory. */ #if defined(MAP_ANON) && defined(HAVE_MMAP) if (munmap(V0, 128 * r * N)) goto err2; #else free(V0); #endif free(XY0); free(B0); /* Success! */ return (0); err2: free(XY0); err1: free(B0); err0: /* Failure! */ return (-1); } #define TESTLEN 64 static struct scrypt_test { const char * passwd; const char * salt; uint64_t N; uint32_t r; uint32_t p; uint8_t result[TESTLEN]; } testcase = { "pleaseletmein", "SodiumChloride", 16, 8, 1, { 0x25, 0xa9, 0xfa, 0x20, 0x7f, 0x87, 0xca, 0x09, 0xa4, 0xef, 0x8b, 0x9f, 0x77, 0x7a, 0xca, 0x16, 0xbe, 0xb7, 0x84, 0xae, 0x18, 0x30, 0xbf, 0xbf, 0xd3, 0x83, 0x25, 0xaa, 0xbb, 0x93, 0x77, 0xdf, 0x1b, 0xa7, 0x84, 0xd7, 0x46, 0xea, 0x27, 0x3b, 0xf5, 0x16, 0xa4, 0x6f, 0xbf, 0xac, 0xf5, 0x11, 0xc5, 0xbe, 0xba, 0x4c, 0x4a, 0xb3, 0xac, 0xc7, 0xfa, 0x6f, 0x46, 0x0b, 0x6c, 0x0f, 0x47, 0x7b, } }; static int testsmix(void (*smix)(uint8_t *, size_t, uint64_t, void *, void *)) { uint8_t hbuf[TESTLEN]; /* Perform the computation. */ if (_crypto_scrypt( (const uint8_t *)testcase.passwd, strlen(testcase.passwd), (const uint8_t *)testcase.salt, strlen(testcase.salt), testcase.N, testcase.r, testcase.p, hbuf, TESTLEN, smix)) return (-1); /* Does it match? */ return (memcmp(testcase.result, hbuf, TESTLEN)); } static void selectsmix(void) { #ifdef CPUSUPPORT_X86_SSE2 /* If we're running on an SSE2-capable CPU, try that code. */ if (cpusupport_x86_sse2()) { /* If SSE2ized smix works, use it. */ if (!testsmix(crypto_scrypt_smix_sse2)) { smix_func = crypto_scrypt_smix_sse2; return; } warn0("Disabling broken SSE2 scrypt support - please report bug!"); } #endif /* If generic smix works, use it. */ if (!testsmix(crypto_scrypt_smix)) { smix_func = crypto_scrypt_smix; return; } warn0("Generic scrypt code is broken - please report bug!"); /* If we get here, something really bad happened. */ abort(); } /** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, * p, buflen) and write the result into buf. The parameters r, p, and buflen * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N * must be a power of 2 greater than 1. * * Return 0 on success; or -1 on error. */ int crypto_scrypt(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t _r, uint32_t _p, uint8_t * buf, size_t buflen) { if (smix_func == NULL) selectsmix(); return (_crypto_scrypt(passwd, passwdlen, salt, saltlen, N, _r, _p, buf, buflen, smix_func)); } scrypt-0.8.0/scrypt-1.2.0/lib/crypto/crypto_scrypt.h0000644000076500000240000000406612561447061022771 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #ifndef _CRYPTO_SCRYPT_H_ #define _CRYPTO_SCRYPT_H_ #include #include /** * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen): * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r, * p, buflen) and write the result into buf. The parameters r, p, and buflen * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N * must be a power of 2 greater than 1. * * Return 0 on success; or -1 on error. */ int crypto_scrypt(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, uint32_t, uint32_t, uint8_t *, size_t); #endif /* !_CRYPTO_SCRYPT_H_ */ scrypt-0.8.0/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c0000644000076500000240000001410012561447061024012 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #include #include #include "sha256.h" #include "sysendian.h" #include "crypto_scrypt_smix.h" static void blkcpy(void *, const void *, size_t); static void blkxor(void *, const void *, size_t); static void salsa20_8(uint32_t[16]); static void blockmix_salsa8(const uint32_t *, uint32_t *, uint32_t *, size_t); static uint64_t integerify(const void *, size_t); static void blkcpy(void * dest, const void * src, size_t len) { size_t * D = dest; const size_t * S = src; size_t L = len / sizeof(size_t); size_t i; for (i = 0; i < L; i++) D[i] = S[i]; } static void blkxor(void * dest, const void * src, size_t len) { size_t * D = dest; const size_t * S = src; size_t L = len / sizeof(size_t); size_t i; for (i = 0; i < L; i++) D[i] ^= S[i]; } /** * salsa20_8(B): * Apply the salsa20/8 core to the provided block. */ static void salsa20_8(uint32_t B[16]) { uint32_t x[16]; size_t i; blkcpy(x, B, 64); for (i = 0; i < 8; i += 2) { #define R(a,b) (((a) << (b)) | ((a) >> (32 - (b)))) /* Operate on columns. */ x[ 4] ^= R(x[ 0]+x[12], 7); x[ 8] ^= R(x[ 4]+x[ 0], 9); x[12] ^= R(x[ 8]+x[ 4],13); x[ 0] ^= R(x[12]+x[ 8],18); x[ 9] ^= R(x[ 5]+x[ 1], 7); x[13] ^= R(x[ 9]+x[ 5], 9); x[ 1] ^= R(x[13]+x[ 9],13); x[ 5] ^= R(x[ 1]+x[13],18); x[14] ^= R(x[10]+x[ 6], 7); x[ 2] ^= R(x[14]+x[10], 9); x[ 6] ^= R(x[ 2]+x[14],13); x[10] ^= R(x[ 6]+x[ 2],18); x[ 3] ^= R(x[15]+x[11], 7); x[ 7] ^= R(x[ 3]+x[15], 9); x[11] ^= R(x[ 7]+x[ 3],13); x[15] ^= R(x[11]+x[ 7],18); /* Operate on rows. */ x[ 1] ^= R(x[ 0]+x[ 3], 7); x[ 2] ^= R(x[ 1]+x[ 0], 9); x[ 3] ^= R(x[ 2]+x[ 1],13); x[ 0] ^= R(x[ 3]+x[ 2],18); x[ 6] ^= R(x[ 5]+x[ 4], 7); x[ 7] ^= R(x[ 6]+x[ 5], 9); x[ 4] ^= R(x[ 7]+x[ 6],13); x[ 5] ^= R(x[ 4]+x[ 7],18); x[11] ^= R(x[10]+x[ 9], 7); x[ 8] ^= R(x[11]+x[10], 9); x[ 9] ^= R(x[ 8]+x[11],13); x[10] ^= R(x[ 9]+x[ 8],18); x[12] ^= R(x[15]+x[14], 7); x[13] ^= R(x[12]+x[15], 9); x[14] ^= R(x[13]+x[12],13); x[15] ^= R(x[14]+x[13],18); #undef R } for (i = 0; i < 16; i++) B[i] += x[i]; } /** * blockmix_salsa8(Bin, Bout, X, r): * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r * bytes in length; the output Bout must also be the same size. The * temporary space X must be 64 bytes. */ static void blockmix_salsa8(const uint32_t * Bin, uint32_t * Bout, uint32_t * X, size_t r) { size_t i; /* 1: X <-- B_{2r - 1} */ blkcpy(X, &Bin[(2 * r - 1) * 16], 64); /* 2: for i = 0 to 2r - 1 do */ for (i = 0; i < 2 * r; i += 2) { /* 3: X <-- H(X \xor B_i) */ blkxor(X, &Bin[i * 16], 64); salsa20_8(X); /* 4: Y_i <-- X */ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ blkcpy(&Bout[i * 8], X, 64); /* 3: X <-- H(X \xor B_i) */ blkxor(X, &Bin[i * 16 + 16], 64); salsa20_8(X); /* 4: Y_i <-- X */ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ blkcpy(&Bout[i * 8 + r * 16], X, 64); } } /** * integerify(B, r): * Return the result of parsing B_{2r-1} as a little-endian integer. */ static uint64_t integerify(const void * B, size_t r) { const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64); return (((uint64_t)(X[1]) << 32) + X[0]); } /** * crypto_scrypt_smix(B, r, N, V, XY): * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; * the temporary storage V must be 128rN bytes in length; the temporary * storage XY must be 256r + 64 bytes in length. The value N must be a * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a * multiple of 64 bytes. */ void crypto_scrypt_smix(uint8_t * B, size_t r, uint64_t N, void * _V, void * XY) { uint32_t * X = XY; uint32_t * Y = (void *)((uint8_t *)(XY) + 128 * r); uint32_t * Z = (void *)((uint8_t *)(XY) + 256 * r); uint32_t * V = _V; uint64_t i; uint64_t j; size_t k; /* 1: X <-- B */ for (k = 0; k < 32 * r; k++) X[k] = le32dec(&B[4 * k]); /* 2: for i = 0 to N - 1 do */ for (i = 0; i < N; i += 2) { /* 3: V_i <-- X */ blkcpy(&V[i * (32 * r)], X, 128 * r); /* 4: X <-- H(X) */ blockmix_salsa8(X, Y, Z, r); /* 3: V_i <-- X */ blkcpy(&V[(i + 1) * (32 * r)], Y, 128 * r); /* 4: X <-- H(X) */ blockmix_salsa8(Y, X, Z, r); } /* 6: for i = 0 to N - 1 do */ for (i = 0; i < N; i += 2) { /* 7: j <-- Integerify(X) mod N */ j = integerify(X, r) & (N - 1); /* 8: X <-- H(X \xor V_j) */ blkxor(X, &V[j * (32 * r)], 128 * r); blockmix_salsa8(X, Y, Z, r); /* 7: j <-- Integerify(X) mod N */ j = integerify(Y, r) & (N - 1); /* 8: X <-- H(X \xor V_j) */ blkxor(Y, &V[j * (32 * r)], 128 * r); blockmix_salsa8(Y, X, Z, r); } /* 10: B' <-- X */ for (k = 0; k < 32 * r; k++) le32enc(&B[4 * k], X[k]); } scrypt-0.8.0/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h0000644000076500000240000000102712561447061024023 0ustar mhallinstaff00000000000000#ifndef _CRYPTO_SCRYPT_SMIX_H_ #define _CRYPTO_SCRYPT_SMIX_H_ /** * crypto_scrypt_smix(B, r, N, V, XY): * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; * the temporary storage V must be 128rN bytes in length; the temporary * storage XY must be 256r + 64 bytes in length. The value N must be a * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a * multiple of 64 bytes. */ void crypto_scrypt_smix(uint8_t *, size_t, uint64_t, void *, void *); #endif /* !_CRYPTO_SCRYPT_SMIX_H_ */ scrypt-0.8.0/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c0000644000076500000240000001544412561447061024762 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #include "cpusupport.h" #ifdef CPUSUPPORT_X86_SSE2 #include #include #include "sysendian.h" #include "crypto_scrypt_smix_sse2.h" static void blkcpy(void *, const void *, size_t); static void blkxor(void *, const void *, size_t); static void salsa20_8(__m128i *); static void blockmix_salsa8(const __m128i *, __m128i *, __m128i *, size_t); static uint64_t integerify(const void *, size_t); static void blkcpy(void * dest, const void * src, size_t len) { __m128i * D = dest; const __m128i * S = src; size_t L = len / 16; size_t i; for (i = 0; i < L; i++) D[i] = S[i]; } static void blkxor(void * dest, const void * src, size_t len) { __m128i * D = dest; const __m128i * S = src; size_t L = len / 16; size_t i; for (i = 0; i < L; i++) D[i] = _mm_xor_si128(D[i], S[i]); } /** * salsa20_8(B): * Apply the salsa20/8 core to the provided block. */ static void salsa20_8(__m128i B[4]) { __m128i X0, X1, X2, X3; __m128i T; size_t i; X0 = B[0]; X1 = B[1]; X2 = B[2]; X3 = B[3]; for (i = 0; i < 8; i += 2) { /* Operate on "columns". */ T = _mm_add_epi32(X0, X3); X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 7)); X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 25)); T = _mm_add_epi32(X1, X0); X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); T = _mm_add_epi32(X2, X1); X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 13)); X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 19)); T = _mm_add_epi32(X3, X2); X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); /* Rearrange data. */ X1 = _mm_shuffle_epi32(X1, 0x93); X2 = _mm_shuffle_epi32(X2, 0x4E); X3 = _mm_shuffle_epi32(X3, 0x39); /* Operate on "rows". */ T = _mm_add_epi32(X0, X1); X3 = _mm_xor_si128(X3, _mm_slli_epi32(T, 7)); X3 = _mm_xor_si128(X3, _mm_srli_epi32(T, 25)); T = _mm_add_epi32(X3, X0); X2 = _mm_xor_si128(X2, _mm_slli_epi32(T, 9)); X2 = _mm_xor_si128(X2, _mm_srli_epi32(T, 23)); T = _mm_add_epi32(X2, X3); X1 = _mm_xor_si128(X1, _mm_slli_epi32(T, 13)); X1 = _mm_xor_si128(X1, _mm_srli_epi32(T, 19)); T = _mm_add_epi32(X1, X2); X0 = _mm_xor_si128(X0, _mm_slli_epi32(T, 18)); X0 = _mm_xor_si128(X0, _mm_srli_epi32(T, 14)); /* Rearrange data. */ X1 = _mm_shuffle_epi32(X1, 0x39); X2 = _mm_shuffle_epi32(X2, 0x4E); X3 = _mm_shuffle_epi32(X3, 0x93); } B[0] = _mm_add_epi32(B[0], X0); B[1] = _mm_add_epi32(B[1], X1); B[2] = _mm_add_epi32(B[2], X2); B[3] = _mm_add_epi32(B[3], X3); } /** * blockmix_salsa8(Bin, Bout, X, r): * Compute Bout = BlockMix_{salsa20/8, r}(Bin). The input Bin must be 128r * bytes in length; the output Bout must also be the same size. The * temporary space X must be 64 bytes. */ static void blockmix_salsa8(const __m128i * Bin, __m128i * Bout, __m128i * X, size_t r) { size_t i; /* 1: X <-- B_{2r - 1} */ blkcpy(X, &Bin[8 * r - 4], 64); /* 2: for i = 0 to 2r - 1 do */ for (i = 0; i < r; i++) { /* 3: X <-- H(X \xor B_i) */ blkxor(X, &Bin[i * 8], 64); salsa20_8(X); /* 4: Y_i <-- X */ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ blkcpy(&Bout[i * 4], X, 64); /* 3: X <-- H(X \xor B_i) */ blkxor(X, &Bin[i * 8 + 4], 64); salsa20_8(X); /* 4: Y_i <-- X */ /* 6: B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */ blkcpy(&Bout[(r + i) * 4], X, 64); } } /** * integerify(B, r): * Return the result of parsing B_{2r-1} as a little-endian integer. */ static uint64_t integerify(const void * B, size_t r) { const uint32_t * X = (const void *)((uintptr_t)(B) + (2 * r - 1) * 64); return (((uint64_t)(X[13]) << 32) + X[0]); } /** * crypto_scrypt_smix_sse2(B, r, N, V, XY): * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; * the temporary storage V must be 128rN bytes in length; the temporary * storage XY must be 256r + 64 bytes in length. The value N must be a * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a * multiple of 64 bytes. * * Use SSE2 instructions. */ void crypto_scrypt_smix_sse2(uint8_t * B, size_t r, uint64_t N, void * V, void * XY) { __m128i * X = XY; __m128i * Y = (void *)((uintptr_t)(XY) + 128 * r); __m128i * Z = (void *)((uintptr_t)(XY) + 256 * r); uint32_t * X32 = (void *)X; uint64_t i, j; size_t k; /* 1: X <-- B */ for (k = 0; k < 2 * r; k++) { for (i = 0; i < 16; i++) { X32[k * 16 + i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]); } } /* 2: for i = 0 to N - 1 do */ for (i = 0; i < N; i += 2) { /* 3: V_i <-- X */ blkcpy((void *)((uintptr_t)(V) + i * 128 * r), X, 128 * r); /* 4: X <-- H(X) */ blockmix_salsa8(X, Y, Z, r); /* 3: V_i <-- X */ blkcpy((void *)((uintptr_t)(V) + (i + 1) * 128 * r), Y, 128 * r); /* 4: X <-- H(X) */ blockmix_salsa8(Y, X, Z, r); } /* 6: for i = 0 to N - 1 do */ for (i = 0; i < N; i += 2) { /* 7: j <-- Integerify(X) mod N */ j = integerify(X, r) & (N - 1); /* 8: X <-- H(X \xor V_j) */ blkxor(X, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r); blockmix_salsa8(X, Y, Z, r); /* 7: j <-- Integerify(X) mod N */ j = integerify(Y, r) & (N - 1); /* 8: X <-- H(X \xor V_j) */ blkxor(Y, (void *)((uintptr_t)(V) + j * 128 * r), 128 * r); blockmix_salsa8(Y, X, Z, r); } /* 10: B' <-- X */ for (k = 0; k < 2 * r; k++) { for (i = 0; i < 16; i++) { le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X32[k * 16 + i]); } } } #endif /* CPUSUPPORT_X86_SSE2 */ scrypt-0.8.0/scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h0000644000076500000240000000111512561447061024755 0ustar mhallinstaff00000000000000#ifndef _CRYPTO_SCRYPT_SMIX_SSE2_H_ #define _CRYPTO_SCRYPT_SMIX_SSE2_H_ /** * crypto_scrypt_smix_sse2(B, r, N, V, XY): * Compute B = SMix_r(B, N). The input B must be 128r bytes in length; * the temporary storage V must be 128rN bytes in length; the temporary * storage XY must be 256r + 64 bytes in length. The value N must be a * power of 2 greater than 1. The arrays B, V, and XY must be aligned to a * multiple of 64 bytes. * * Use SSE2 instructions. */ void crypto_scrypt_smix_sse2(uint8_t *, size_t, uint64_t, void *, void *); #endif /* !_CRYPTO_SCRYPT_SMIX_SSE2_H_ */ scrypt-0.8.0/scrypt-1.2.0/lib/scryptenc/0000755000076500000240000000000012767242550020364 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/lib/scryptenc/scryptenc.c0000644000076500000240000003505412561447061022545 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #include "scrypt_platform.h" #include #include #include #include #include #include #include "crypto_aes.h" #include "crypto_aesctr.h" #include "crypto_entropy.h" #include "insecure_memzero.h" #include "sha256.h" #include "sysendian.h" #include "crypto_scrypt.h" #include "memlimit.h" #include "scryptenc_cpuperf.h" #include "scryptenc.h" #define ENCBLOCK 65536 static int pickparams(size_t, double, double, int *, uint32_t *, uint32_t *); static int checkparams(size_t, double, double, int, uint32_t, uint32_t); static int pickparams(size_t maxmem, double maxmemfrac, double maxtime, int * logN, uint32_t * r, uint32_t * p) { size_t memlimit; double opps; double opslimit; double maxN, maxrp; int rc; /* Figure out how much memory to use. */ if (memtouse(maxmem, maxmemfrac, &memlimit)) return (1); /* Figure out how fast the CPU is. */ if ((rc = scryptenc_cpuperf(&opps)) != 0) return (rc); opslimit = opps * maxtime; /* Allow a minimum of 2^15 salsa20/8 cores. */ if (opslimit < 32768) opslimit = 32768; /* Fix r = 8 for now. */ *r = 8; /* * The memory limit requires that 128Nr <= memlimit, while the CPU * limit requires that 4Nrp <= opslimit. If opslimit < memlimit/32, * opslimit imposes the stronger limit on N. */ #ifdef DEBUG fprintf(stderr, "Requiring 128Nr <= %zu, 4Nrp <= %f\n", memlimit, opslimit); #endif if (opslimit < memlimit/32) { /* Set p = 1 and choose N based on the CPU limit. */ *p = 1; maxN = opslimit / (*r * 4); for (*logN = 1; *logN < 63; *logN += 1) { if ((uint64_t)(1) << *logN > maxN / 2) break; } } else { /* Set N based on the memory limit. */ maxN = memlimit / (*r * 128); for (*logN = 1; *logN < 63; *logN += 1) { if ((uint64_t)(1) << *logN > maxN / 2) break; } /* Choose p based on the CPU limit. */ maxrp = (opslimit / 4) / ((uint64_t)(1) << *logN); if (maxrp > 0x3fffffff) maxrp = 0x3fffffff; *p = (uint32_t)(maxrp) / *r; } #ifdef DEBUG fprintf(stderr, "N = %zu r = %d p = %d\n", (size_t)(1) << *logN, (int)(*r), (int)(*p)); #endif /* Success! */ return (0); } static int checkparams(size_t maxmem, double maxmemfrac, double maxtime, int logN, uint32_t r, uint32_t p) { size_t memlimit; double opps; double opslimit; uint64_t N; int rc; /* Figure out the maximum amount of memory we can use. */ if (memtouse(maxmem, maxmemfrac, &memlimit)) return (1); /* Figure out how fast the CPU is. */ if ((rc = scryptenc_cpuperf(&opps)) != 0) return (rc); opslimit = opps * maxtime; /* Sanity-check values. */ if ((logN < 1) || (logN > 63)) return (7); if ((uint64_t)(r) * (uint64_t)(p) >= 0x40000000) return (7); /* Check limits. */ N = (uint64_t)(1) << logN; if ((memlimit / N) / r < 128) return (9); if ((opslimit / N) / (r * p) < 4) return (10); /* Success! */ return (0); } static int scryptenc_setup(uint8_t header[96], uint8_t dk[64], const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t salt[32]; uint8_t hbuf[32]; int logN; uint64_t N; uint32_t r; uint32_t p; SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; HMAC_SHA256_CTX hctx; int rc; /* Pick values for N, r, p. */ if ((rc = pickparams(maxmem, maxmemfrac, maxtime, &logN, &r, &p)) != 0) return (rc); N = (uint64_t)(1) << logN; /* Get some salt. */ if (crypto_entropy_read(salt, 32)) return (4); /* Generate the derived keys. */ if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64)) return (3); /* Construct the file header. */ memcpy(header, "scrypt", 6); header[6] = 0; header[7] = logN; be32enc(&header[8], r); be32enc(&header[12], p); memcpy(&header[16], salt, 32); /* Add header checksum. */ SHA256_Init(&ctx); SHA256_Update(&ctx, header, 48); SHA256_Final(hbuf, &ctx); memcpy(&header[48], hbuf, 16); /* Add header signature (used for verifying password). */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 64); HMAC_SHA256_Final(hbuf, &hctx); memcpy(&header[64], hbuf, 32); /* Success! */ return (0); } static int scryptdec_setup(const uint8_t header[96], uint8_t dk[64], const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t salt[32]; uint8_t hbuf[32]; int logN; uint32_t r; uint32_t p; uint64_t N; SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; HMAC_SHA256_CTX hctx; int rc; /* Parse N, r, p, salt. */ logN = header[7]; r = be32dec(&header[8]); p = be32dec(&header[12]); memcpy(salt, &header[16], 32); /* Verify header checksum. */ SHA256_Init(&ctx); SHA256_Update(&ctx, header, 48); SHA256_Final(hbuf, &ctx); if (memcmp(&header[48], hbuf, 16)) return (7); /* * Check whether the provided parameters are valid and whether the * key derivation function can be computed within the allowed memory * and CPU time. */ if ((rc = checkparams(maxmem, maxmemfrac, maxtime, logN, r, p)) != 0) return (rc); /* Compute the derived keys. */ N = (uint64_t)(1) << logN; if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64)) return (3); /* Check header signature (i.e., verify password). */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 64); HMAC_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, &header[64], 32)) return (11); /* Success! */ return (0); } /** * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128 * bytes to outbuf. */ int scryptenc_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t dk[64]; uint8_t hbuf[32]; uint8_t header[96]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; int rc; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; /* Generate the header and derived key. */ if ((rc = scryptenc_setup(header, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Copy header into output buffer. */ memcpy(outbuf, header, 96); /* Encrypt data. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); crypto_aesctr_stream(AES, inbuf, &outbuf[96], inbuflen); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); /* Add signature. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, outbuf, 96 + inbuflen); HMAC_SHA256_Final(hbuf, &hctx); memcpy(&outbuf[96 + inbuflen], hbuf, 32); /* Zero sensitive data. */ insecure_memzero(dk, 64); /* Success! */ return (0); } /** * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the * decrypted data length to outlen. The allocated length of outbuf must * be at least inbuflen. */ int scryptdec_buf(const uint8_t * inbuf, size_t inbuflen, uint8_t * outbuf, size_t * outlen, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t hbuf[32]; uint8_t dk[64]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; int rc; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; /* * All versions of the scrypt format will start with "scrypt" and * have at least 7 bytes of header. */ if ((inbuflen < 7) || (memcmp(inbuf, "scrypt", 6) != 0)) return (7); /* Check the format. */ if (inbuf[6] != 0) return (8); /* We must have at least 128 bytes. */ if (inbuflen < 128) return (7); /* Parse the header and generate derived keys. */ if ((rc = scryptdec_setup(inbuf, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Decrypt data. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); crypto_aesctr_stream(AES, &inbuf[96], outbuf, inbuflen - 128); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); *outlen = inbuflen - 128; /* Verify signature. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, inbuf, inbuflen - 32); HMAC_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, &inbuf[inbuflen - 32], 32)) return (7); /* Zero sensitive data. */ insecure_memzero(dk, 64); /* Success! */ return (0); } /** * scryptenc_file(infile, outfile, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Read a stream from infile and encrypt it, writing the resulting stream to * outfile. */ int scryptenc_file(FILE * infile, FILE * outfile, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t buf[ENCBLOCK]; uint8_t dk[64]; uint8_t hbuf[32]; uint8_t header[96]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; size_t readlen; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; int rc; /* Generate the header and derived key. */ if ((rc = scryptenc_setup(header, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Hash and write the header. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 96); if (fwrite(header, 96, 1, outfile) != 1) return (12); /* * Read blocks of data, encrypt them, and write them out; hash the * data as it is produced. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); do { if ((readlen = fread(buf, 1, ENCBLOCK, infile)) == 0) break; crypto_aesctr_stream(AES, buf, buf, readlen); HMAC_SHA256_Update(&hctx, buf, readlen); if (fwrite(buf, 1, readlen, outfile) < readlen) { crypto_aesctr_free(AES); return (12); } } while (1); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); /* Did we exit the loop due to a read error? */ if (ferror(infile)) return (13); /* Compute the final HMAC and output it. */ HMAC_SHA256_Final(hbuf, &hctx); if (fwrite(hbuf, 32, 1, outfile) != 1) return (12); /* Zero sensitive data. */ insecure_memzero(dk, 64); /* Success! */ return (0); } /** * scryptdec_file(infile, outfile, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Read a stream from infile and decrypt it, writing the resulting stream to * outfile. */ int scryptdec_file(FILE * infile, FILE * outfile, const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t buf[ENCBLOCK + 32]; uint8_t header[96]; uint8_t hbuf[32]; uint8_t dk[64]; uint8_t * key_enc = dk; uint8_t * key_hmac = &dk[32]; size_t buflen = 0; size_t readlen; HMAC_SHA256_CTX hctx; struct crypto_aes_key * key_enc_exp; struct crypto_aesctr * AES; int rc; /* * Read the first 7 bytes of the file; all future versions of scrypt * are guaranteed to have at least 7 bytes of header. */ if (fread(header, 7, 1, infile) < 1) { if (ferror(infile)) return (13); else return (7); } /* Do we have the right magic? */ if (memcmp(header, "scrypt", 6)) return (7); if (header[6] != 0) return (8); /* * Read another 89 bytes of the file; version 0 of the scrypt file * format has a 96-byte header. */ if (fread(&header[7], 89, 1, infile) < 1) { if (ferror(infile)) return (13); else return (7); } /* Parse the header and generate derived keys. */ if ((rc = scryptdec_setup(header, dk, passwd, passwdlen, maxmem, maxmemfrac, maxtime)) != 0) return (rc); /* Start hashing with the header. */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 96); /* * We don't know how long the encrypted data block is (we can't know, * since data can be streamed into 'scrypt enc') so we need to read * data and decrypt all of it except the final 32 bytes, then check * if that final 32 bytes is the correct signature. */ if ((key_enc_exp = crypto_aes_key_expand(key_enc, 32)) == NULL) return (5); if ((AES = crypto_aesctr_init(key_enc_exp, 0)) == NULL) return (6); do { /* Read data until we have more than 32 bytes of it. */ if ((readlen = fread(&buf[buflen], 1, ENCBLOCK + 32 - buflen, infile)) == 0) break; buflen += readlen; if (buflen <= 32) continue; /* * Decrypt, hash, and output everything except the last 32 * bytes out of what we have in our buffer. */ HMAC_SHA256_Update(&hctx, buf, buflen - 32); crypto_aesctr_stream(AES, buf, buf, buflen - 32); if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) { crypto_aesctr_free(AES); return (12); } /* Move the last 32 bytes to the start of the buffer. */ memmove(buf, &buf[buflen - 32], 32); buflen = 32; } while (1); crypto_aesctr_free(AES); crypto_aes_key_free(key_enc_exp); /* Did we exit the loop due to a read error? */ if (ferror(infile)) return (13); /* Did we read enough data that we *might* have a valid signature? */ if (buflen < 32) return (7); /* Verify signature. */ HMAC_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, buf, 32)) return (7); /* Zero sensitive data. */ insecure_memzero(dk, 64); return (0); } scrypt-0.8.0/scrypt-1.2.0/lib/scryptenc/scryptenc.h0000644000076500000240000001170312561447061022545 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #ifndef _SCRYPTENC_H_ #define _SCRYPTENC_H_ #include #include /** * NOTE: This file provides prototypes for routines which encrypt/decrypt data * using a key derived from a password by using the scrypt key derivation * function. If you are just trying to "hash" a password for user logins, * this is not the code you are looking for. You want to use the crypt_scrypt * function directly. */ /** * The parameters maxmem, maxmemfrac, and maxtime used by all of these * functions are defined as follows: * maxmem - maximum number of bytes of storage to use for V array (which is * by far the largest consumer of memory). If this value is set to 0, no * maximum will be enforced; any other value less than 1 MiB will be * treated as 1 MiB. * maxmemfrac - maximum fraction of available storage to use for the V array, * where "available storage" is defined as the minimum out of the * RLIMIT_AS, RLIMIT_DATA. and RLIMIT_RSS resource limits (if any are * set). If this value is set to 0 or more than 0.5 it will be treated * as 0.5; and this value will never cause a limit of less than 1 MiB to * be enforced. * maxtime - maximum amount of CPU time to spend computing the derived keys, * in seconds. This limit is only approximately enforced; the CPU * performance is estimated and parameter limits are chosen accordingly. * For the encryption functions, the parameters to the scrypt key derivation * function are chosen to make the key as strong as possible subject to the * specified limits; for the decryption functions, the parameters used are * compared to the computed limits and an error is returned if decrypting * the data would take too much memory or CPU time. */ /** * Return codes from scrypt(enc|dec)_(buf|file): * 0 success * 1 getrlimit or sysctl(hw.usermem) failed * 2 clock_getres or clock_gettime failed * 3 error computing derived key * 4 could not read salt from /dev/urandom * 5 error in OpenSSL * 6 malloc failed * 7 data is not a valid scrypt-encrypted block * 8 unrecognized scrypt format * 9 decrypting file would take too much memory * 10 decrypting file would take too long * 11 password is incorrect * 12 error writing output file * 13 error reading input file */ /** * scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Encrypt inbuflen bytes from inbuf, writing the resulting inbuflen + 128 * bytes to outbuf. */ int scryptenc_buf(const uint8_t *, size_t, uint8_t *, const uint8_t *, size_t, size_t, double, double); /** * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Decrypt inbuflen bytes from inbuf, writing the result into outbuf and the * decrypted data length to outlen. The allocated length of outbuf must * be at least inbuflen. */ int scryptdec_buf(const uint8_t *, size_t, uint8_t *, size_t *, const uint8_t *, size_t, size_t, double, double); /** * scryptenc_file(infile, outfile, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Read a stream from infile and encrypt it, writing the resulting stream to * outfile. */ int scryptenc_file(FILE *, FILE *, const uint8_t *, size_t, size_t, double, double); /** * scryptdec_file(infile, outfile, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Read a stream from infile and decrypt it, writing the resulting stream to * outfile. */ int scryptdec_file(FILE *, FILE *, const uint8_t *, size_t, size_t, double, double); #endif /* !_SCRYPTENC_H_ */ scrypt-0.8.0/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c0000644000076500000240000001047112561447061024265 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #include "scrypt_platform.h" #include #include #include #include #include "crypto_scrypt.h" #include "scryptenc_cpuperf.h" #ifdef HAVE_CLOCK_GETTIME static clock_t clocktouse; static int getclockres(double * resd) { struct timespec res; /* * Try clocks in order of preference until we find one which works. * (We assume that if clock_getres works, clock_gettime will, too.) * The use of if/else/if/else/if/else rather than if/elif/elif/else * is ugly but legal, and allows us to #ifdef things appropriately. */ #ifdef CLOCK_VIRTUAL if (clock_getres(CLOCK_VIRTUAL, &res) == 0) clocktouse = CLOCK_VIRTUAL; else #endif #ifdef CLOCK_MONOTONIC if (clock_getres(CLOCK_MONOTONIC, &res) == 0) clocktouse = CLOCK_MONOTONIC; else #endif if (clock_getres(CLOCK_REALTIME, &res) == 0) clocktouse = CLOCK_REALTIME; else return (-1); /* Convert clock resolution to a double. */ *resd = res.tv_sec + res.tv_nsec * 0.000000001; return (0); } static int getclocktime(struct timespec * ts) { if (clock_gettime(clocktouse, ts)) return (-1); return (0); } #else static int getclockres(double * resd) { *resd = 1.0 / CLOCKS_PER_SEC; return (0); } static int getclocktime(struct timespec * ts) { struct timeval tv; if (gettimeofday(&tv, NULL)) return (-1); ts->tv_sec = tv.tv_sec; ts->tv_nsec = tv.tv_usec * 1000; return (0); } #endif static int getclockdiff(struct timespec * st, double * diffd) { struct timespec en; if (getclocktime(&en)) return (1); *diffd = (en.tv_nsec - st->tv_nsec) * 0.000000001 + (en.tv_sec - st->tv_sec); return (0); } /** * scryptenc_cpuperf(opps): * Estimate the number of salsa20/8 cores which can be executed per second, * and return the value via opps. */ int scryptenc_cpuperf(double * opps) { struct timespec st; double resd, diffd; uint64_t i = 0; /* Get the clock resolution. */ if (getclockres(&resd)) return (2); #ifdef DEBUG fprintf(stderr, "Clock resolution is %f\n", resd); #endif /* Loop until the clock ticks. */ if (getclocktime(&st)) return (2); do { /* Do an scrypt. */ if (crypto_scrypt(NULL, 0, NULL, 0, 16, 1, 1, NULL, 0)) return (3); /* Has the clock ticked? */ if (getclockdiff(&st, &diffd)) return (2); if (diffd > 0) break; } while (1); /* Count how many scrypts we can do before the next tick. */ if (getclocktime(&st)) return (2); do { /* Do an scrypt. */ if (crypto_scrypt(NULL, 0, NULL, 0, 128, 1, 1, NULL, 0)) return (3); /* We invoked the salsa20/8 core 512 times. */ i += 512; /* Check if we have looped for long enough. */ if (getclockdiff(&st, &diffd)) return (2); if (diffd > resd) break; } while (1); #ifdef DEBUG fprintf(stderr, "%ju salsa20/8 cores performed in %f seconds\n", (uintmax_t)i, diffd); #endif /* We can do approximately i salsa20/8 cores per diffd seconds. */ *opps = i / diffd; return (0); } scrypt-0.8.0/scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h0000644000076500000240000000330612561447061024271 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #ifndef _SCRYPTENC_CPUPERF_H_ #define _SCRYPTENC_CPUPERF_H_ /** * scryptenc_cpuperf(opps): * Estimate the number of salsa20/8 cores which can be executed per second, * and return the value via opps. */ int scryptenc_cpuperf(double *); #endif /* !_SCRYPTENC_CPUPERF_H_ */ scrypt-0.8.0/scrypt-1.2.0/lib/util/0000755000076500000240000000000012767242550017327 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/lib/util/memlimit.c0000644000076500000240000002025712767234677021331 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #include "scrypt_platform.h" #include #ifndef _WIN32 #include #else #define _WIN32_WINNT 0x0502 #include #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYS_SYSCTL_H #include #endif #ifdef HAVE_SYS_SYSINFO_H #include #endif #include #include #include #include #include #ifdef DEBUG #include #endif #include "memlimit.h" /* If we don't have CTL_HW, we can't use HW_USERMEM. */ #ifndef CTL_HW #undef HW_USERMEM #endif #ifdef CTL_HW static int memlimit_sysctl_hw(size_t * memlimit, int mibleaf) { int mib[2]; uint8_t sysctlbuf[8]; size_t sysctlbuflen = 8; uint64_t sysctlval; /* Ask the kernel how much RAM we have. */ mib[0] = CTL_HW; mib[1] = mibleaf; if (sysctl(mib, 2, sysctlbuf, &sysctlbuflen, NULL, 0)) return (1); /* * If we read 8 bytes out, assume this is a system-endian uint64_t. * If we only read 4 bytes out, the OS is trying to give us a * uint32_t answer -- but given how many systems now have 4GB+ of RAM, * it's probably truncating, and we really can't trust the value we * have returned to us. */ if (sysctlbuflen == sizeof(uint64_t)) memcpy(&sysctlval, sysctlbuf, sizeof(uint64_t)); else if (sysctlbuflen == sizeof(uint32_t)) sysctlval = SIZE_MAX; else return (1); /* Return the sysctl value, but clamp to SIZE_MAX if necessary. */ #if UINT64_MAX > SIZE_MAX if (sysctlval > SIZE_MAX) *memlimit = SIZE_MAX; else *memlimit = sysctlval; #else *memlimit = sysctlval; #endif /* Success! */ return (0); } #endif /* If we don't HAVE_STRUCT_SYSINFO, we can't use sysinfo. */ #ifndef HAVE_STRUCT_SYSINFO #undef HAVE_SYSINFO #endif /* If we don't HAVE_STRUCT_SYSINFO_TOTALRAM, we can't use sysinfo. */ #ifndef HAVE_STRUCT_SYSINFO_TOTALRAM #undef HAVE_SYSINFO #endif #ifdef HAVE_SYSINFO static int memlimit_sysinfo(size_t * memlimit) { struct sysinfo info; uint64_t totalmem; /* Get information from the kernel. */ if (sysinfo(&info)) return (1); totalmem = info.totalram; /* If we're on a modern kernel, adjust based on mem_unit. */ #ifdef HAVE_STRUCT_SYSINFO_MEM_UNIT totalmem = totalmem * info.mem_unit; #endif /* Return the value, but clamp to SIZE_MAX if necessary. */ #if UINT64_MAX > SIZE_MAX if (totalmem > SIZE_MAX) *memlimit = SIZE_MAX; else *memlimit = totalmem; #else *memlimit = totalmem; #endif /* Success! */ return (0); } #endif /* HAVE_SYSINFO */ #ifndef _WIN32 static int memlimit_rlimit(size_t * memlimit) { struct rlimit rl; uint64_t memrlimit; /* Find the least of... */ memrlimit = (uint64_t)(-1); /* ... RLIMIT_AS... */ #ifdef RLIMIT_AS if (getrlimit(RLIMIT_AS, &rl)) return (1); if ((rl.rlim_cur != RLIM_INFINITY) && ((uint64_t)rl.rlim_cur < memrlimit)) memrlimit = rl.rlim_cur; #endif /* ... RLIMIT_DATA... */ if (getrlimit(RLIMIT_DATA, &rl)) return (1); if ((rl.rlim_cur != RLIM_INFINITY) && ((uint64_t)rl.rlim_cur < memrlimit)) memrlimit = rl.rlim_cur; /* ... and RLIMIT_RSS. */ #ifdef RLIMIT_RSS if (getrlimit(RLIMIT_RSS, &rl)) return (1); if ((rl.rlim_cur != RLIM_INFINITY) && ((uint64_t)rl.rlim_cur < memrlimit)) memrlimit = rl.rlim_cur; #endif /* Return the value, but clamp to SIZE_MAX if necessary. */ #if UINT64_MAX > SIZE_MAX if (memrlimit > SIZE_MAX) *memlimit = SIZE_MAX; else *memlimit = memrlimit; #else *memlimit = memrlimit; #endif /* Success! */ return (0); } #endif #ifdef _SC_PHYS_PAGES /* Some systems define _SC_PAGESIZE instead of _SC_PAGE_SIZE. */ #ifndef _SC_PAGE_SIZE #define _SC_PAGE_SIZE _SC_PAGESIZE #endif static int memlimit_sysconf(size_t * memlimit) { long pagesize; long physpages; uint64_t totalmem; /* Set errno to 0 in order to distinguish "no limit" from "error". */ errno = 0; /* Read the two limits. */ if (((pagesize = sysconf(_SC_PAGE_SIZE)) == -1) || ((physpages = sysconf(_SC_PHYS_PAGES)) == -1)) { /* Did an error occur? */ if (errno != 0) return (1); /* If not, there is no limit. */ totalmem = (uint64_t)(-1); } else { /* Compute the limit. */ totalmem = (uint64_t)(pagesize) * (uint64_t)(physpages); } /* Return the value, but clamp to SIZE_MAX if necessary. */ #if UINT64_MAX > SIZE_MAX if (totalmem > SIZE_MAX) *memlimit = SIZE_MAX; else *memlimit = totalmem; #else *memlimit = totalmem; #endif /* Success! */ return (0); } #endif #ifdef _WIN32 static int memlimit_windows(size_t * memlimit) { MEMORYSTATUSEX state; state.dwLength = sizeof(state); if(!GlobalMemoryStatusEx (&state)) return (1); *memlimit = state.ullTotalPhys; return (0); } #endif int memtouse(size_t maxmem, double maxmemfrac, size_t * memlimit) { size_t usermem_memlimit, memsize_memlimit; size_t sysinfo_memlimit, rlimit_memlimit; size_t sysconf_memlimit, windows_memlimit; size_t memlimit_min; size_t memavail; /* Get memory limits. */ #ifdef HW_USERMEM if (memlimit_sysctl_hw(&usermem_memlimit, HW_USERMEM)) return (1); #else usermem_memlimit = SIZE_MAX; #endif #ifdef HW_MEMSIZE if (memlimit_sysctl_hw(&memsize_memlimit, HW_MEMSIZE)) return (1); #else memsize_memlimit = SIZE_MAX; #endif #ifdef HAVE_SYSINFO if (memlimit_sysinfo(&sysinfo_memlimit)) return (1); #else sysinfo_memlimit = SIZE_MAX; #endif #ifndef _WIN32 if (memlimit_rlimit(&rlimit_memlimit)) return (1); #else rlimit_memlimit = SIZE_MAX; #endif #ifdef _SC_PHYS_PAGES if (memlimit_sysconf(&sysconf_memlimit)) return (1); #else sysconf_memlimit = SIZE_MAX; #endif #ifdef _WIN32 if (memlimit_windows(&windows_memlimit)) return (1); #else windows_memlimit = SIZE_MAX; #endif #ifdef DEBUG fprintf(stderr, "Memory limits are %zu %zu %zu %zu %zu\n", usermem_memlimit, memsize_memlimit, sysinfo_memlimit, rlimit_memlimit, sysconf_memlimit); #endif /* Find the smallest of them. */ memlimit_min = SIZE_MAX; if (memlimit_min > usermem_memlimit) memlimit_min = usermem_memlimit; if (memlimit_min > memsize_memlimit) memlimit_min = memsize_memlimit; if (memlimit_min > sysinfo_memlimit) memlimit_min = sysinfo_memlimit; if (memlimit_min > rlimit_memlimit) memlimit_min = rlimit_memlimit; if (memlimit_min > sysconf_memlimit) memlimit_min = sysconf_memlimit; if (memlimit_min > windows_memlimit) memlimit_min = windows_memlimit; /* Only use the specified fraction of the available memory. */ if ((maxmemfrac > 0.5) || (maxmemfrac == 0.0)) maxmemfrac = 0.5; memavail = maxmemfrac * memlimit_min; /* Don't use more than the specified maximum. */ if ((maxmem > 0) && (memavail > maxmem)) memavail = maxmem; /* But always allow at least 1 MiB. */ if (memavail < 1048576) memavail = 1048576; #ifdef DEBUG fprintf(stderr, "Allowing up to %zu memory to be used\n", memavail); #endif /* Return limit via the provided pointer. */ *memlimit = memavail; return (0); } scrypt-0.8.0/scrypt-1.2.0/lib/util/memlimit.h0000644000076500000240000000344312561447061021315 0ustar mhallinstaff00000000000000/*- * Copyright 2009 Colin Percival * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * This file was originally written by Colin Percival as part of the Tarsnap * online backup system. */ #ifndef _MEMLIMIT_H_ #define _MEMLIMIT_H_ #include /** * memtouse(maxmem, maxmemfrac, memlimit): * Examine the system and return via memlimit the amount of RAM which should * be used -- the specified fraction of the available RAM, but no more than * maxmem, and no less than 1MiB. */ int memtouse(size_t, double, size_t *); #endif /* !_MEMLIMIT_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/0000755000076500000240000000000012767242550020067 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/libcperciva/alg/0000755000076500000240000000000012767242550020632 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/libcperciva/alg/sha256.c0000644000076500000240000002526112561447061022010 0ustar mhallinstaff00000000000000#include #include #include #include "insecure_memzero.h" #include "sysendian.h" #include "sha256.h" /* * Encode a length len/4 vector of (uint32_t) into a length len vector of * (uint8_t) in big-endian form. Assumes len is a multiple of 4. */ static void be32enc_vect(uint8_t * dst, const uint32_t * src, size_t len) { size_t i; /* Sanity-check. */ assert(len % 4 == 0); /* Encode vector, one word at a time. */ for (i = 0; i < len / 4; i++) be32enc(dst + i * 4, src[i]); } /* * Decode a big-endian length len vector of (uint8_t) into a length * len/4 vector of (uint32_t). Assumes len is a multiple of 4. */ static void be32dec_vect(uint32_t * dst, const uint8_t * src, size_t len) { size_t i; /* Sanity-check. */ assert(len % 4 == 0); /* Decode vector, one word at a time. */ for (i = 0; i < len / 4; i++) dst[i] = be32dec(src + i * 4); } /* Elementary functions used by SHA256 */ #define Ch(x, y, z) ((x & (y ^ z)) ^ z) #define Maj(x, y, z) ((x & (y | z)) | (y & z)) #define SHR(x, n) (x >> n) #define ROTR(x, n) ((x >> n) | (x << (32 - n))) #define S0(x) (ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22)) #define S1(x) (ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25)) #define s0(x) (ROTR(x, 7) ^ ROTR(x, 18) ^ SHR(x, 3)) #define s1(x) (ROTR(x, 17) ^ ROTR(x, 19) ^ SHR(x, 10)) /* SHA256 round function */ #define RND(a, b, c, d, e, f, g, h, k) \ t0 = h + S1(e) + Ch(e, f, g) + k; \ t1 = S0(a) + Maj(a, b, c); \ d += t0; \ h = t0 + t1; /* Adjusted round function for rotating state */ #define RNDr(S, W, i, k) \ RND(S[(64 - i) % 8], S[(65 - i) % 8], \ S[(66 - i) % 8], S[(67 - i) % 8], \ S[(68 - i) % 8], S[(69 - i) % 8], \ S[(70 - i) % 8], S[(71 - i) % 8], \ W[i] + k) /* * SHA256 block compression function. The 256-bit state is transformed via * the 512-bit input block to produce a new state. */ static void SHA256_Transform(uint32_t * state, const uint8_t block[64]) { uint32_t W[64]; uint32_t S[8]; uint32_t t0, t1; int i; /* 1. Prepare message schedule W. */ be32dec_vect(W, block, 64); for (i = 16; i < 64; i++) W[i] = s1(W[i - 2]) + W[i - 7] + s0(W[i - 15]) + W[i - 16]; /* 2. Initialize working variables. */ memcpy(S, state, 32); /* 3. Mix. */ RNDr(S, W, 0, 0x428a2f98); RNDr(S, W, 1, 0x71374491); RNDr(S, W, 2, 0xb5c0fbcf); RNDr(S, W, 3, 0xe9b5dba5); RNDr(S, W, 4, 0x3956c25b); RNDr(S, W, 5, 0x59f111f1); RNDr(S, W, 6, 0x923f82a4); RNDr(S, W, 7, 0xab1c5ed5); RNDr(S, W, 8, 0xd807aa98); RNDr(S, W, 9, 0x12835b01); RNDr(S, W, 10, 0x243185be); RNDr(S, W, 11, 0x550c7dc3); RNDr(S, W, 12, 0x72be5d74); RNDr(S, W, 13, 0x80deb1fe); RNDr(S, W, 14, 0x9bdc06a7); RNDr(S, W, 15, 0xc19bf174); RNDr(S, W, 16, 0xe49b69c1); RNDr(S, W, 17, 0xefbe4786); RNDr(S, W, 18, 0x0fc19dc6); RNDr(S, W, 19, 0x240ca1cc); RNDr(S, W, 20, 0x2de92c6f); RNDr(S, W, 21, 0x4a7484aa); RNDr(S, W, 22, 0x5cb0a9dc); RNDr(S, W, 23, 0x76f988da); RNDr(S, W, 24, 0x983e5152); RNDr(S, W, 25, 0xa831c66d); RNDr(S, W, 26, 0xb00327c8); RNDr(S, W, 27, 0xbf597fc7); RNDr(S, W, 28, 0xc6e00bf3); RNDr(S, W, 29, 0xd5a79147); RNDr(S, W, 30, 0x06ca6351); RNDr(S, W, 31, 0x14292967); RNDr(S, W, 32, 0x27b70a85); RNDr(S, W, 33, 0x2e1b2138); RNDr(S, W, 34, 0x4d2c6dfc); RNDr(S, W, 35, 0x53380d13); RNDr(S, W, 36, 0x650a7354); RNDr(S, W, 37, 0x766a0abb); RNDr(S, W, 38, 0x81c2c92e); RNDr(S, W, 39, 0x92722c85); RNDr(S, W, 40, 0xa2bfe8a1); RNDr(S, W, 41, 0xa81a664b); RNDr(S, W, 42, 0xc24b8b70); RNDr(S, W, 43, 0xc76c51a3); RNDr(S, W, 44, 0xd192e819); RNDr(S, W, 45, 0xd6990624); RNDr(S, W, 46, 0xf40e3585); RNDr(S, W, 47, 0x106aa070); RNDr(S, W, 48, 0x19a4c116); RNDr(S, W, 49, 0x1e376c08); RNDr(S, W, 50, 0x2748774c); RNDr(S, W, 51, 0x34b0bcb5); RNDr(S, W, 52, 0x391c0cb3); RNDr(S, W, 53, 0x4ed8aa4a); RNDr(S, W, 54, 0x5b9cca4f); RNDr(S, W, 55, 0x682e6ff3); RNDr(S, W, 56, 0x748f82ee); RNDr(S, W, 57, 0x78a5636f); RNDr(S, W, 58, 0x84c87814); RNDr(S, W, 59, 0x8cc70208); RNDr(S, W, 60, 0x90befffa); RNDr(S, W, 61, 0xa4506ceb); RNDr(S, W, 62, 0xbef9a3f7); RNDr(S, W, 63, 0xc67178f2); /* 4. Mix local working variables into global state. */ for (i = 0; i < 8; i++) state[i] += S[i]; /* Clean the stack. */ insecure_memzero(W, 256); insecure_memzero(S, 32); insecure_memzero(&t0, sizeof(uint32_t)); insecure_memzero(&t1, sizeof(uint32_t)); } static uint8_t PAD[64] = { 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; /* Add padding and terminating bit-count. */ static void SHA256_Pad(SHA256_CTX * ctx) { uint8_t len[8]; uint32_t r, plen; /* * Convert length to a vector of bytes -- we do this now rather * than later because the length will change after we pad. */ be64enc(len, ctx->count); /* Add 1--64 bytes so that the resulting length is 56 mod 64. */ r = (ctx->count >> 3) & 0x3f; plen = (r < 56) ? (56 - r) : (120 - r); SHA256_Update(ctx, PAD, (size_t)plen); /* Add the terminating bit-count. */ SHA256_Update(ctx, len, 8); } /* Magic initialization constants. */ static const uint32_t initstate[8] = { 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 }; /** * SHA256_Init(ctx): * Initialize the SHA256 context ${ctx}. */ void SHA256_Init(SHA256_CTX * ctx) { /* Zero bits processed so far. */ ctx->count = 0; /* Initialize state. */ memcpy(ctx->state, initstate, sizeof(initstate)); } /** * SHA256_Update(ctx, in, len): * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. */ void SHA256_Update(SHA256_CTX * ctx, const void * in, size_t len) { uint32_t r; const uint8_t * src = in; /* Return immediately if we have nothing to do. */ if (len == 0) return; /* Number of bytes left in the buffer from previous updates. */ r = (ctx->count >> 3) & 0x3f; /* Update number of bits. */ ctx->count += (uint64_t)(len) << 3; /* Handle the case where we don't need to perform any transforms. */ if (len < 64 - r) { memcpy(&ctx->buf[r], src, len); return; } /* Finish the current block. */ memcpy(&ctx->buf[r], src, 64 - r); SHA256_Transform(ctx->state, ctx->buf); src += 64 - r; len -= 64 - r; /* Perform complete blocks. */ while (len >= 64) { SHA256_Transform(ctx->state, src); src += 64; len -= 64; } /* Copy left over data into buffer. */ memcpy(ctx->buf, src, len); } /** * SHA256_Final(digest, ctx): * Output the SHA256 hash of the data input to the context ${ctx} into the * buffer ${digest}. */ void SHA256_Final(uint8_t digest[32], SHA256_CTX * ctx) { /* Add padding. */ SHA256_Pad(ctx); /* Write the hash. */ be32enc_vect(digest, ctx->state, 32); /* Clear the context state. */ insecure_memzero(ctx, sizeof(SHA256_CTX)); } /** * SHA256_Buf(in, len, digest): * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}. */ void SHA256_Buf(const void * in, size_t len, uint8_t digest[32]) { SHA256_CTX ctx; SHA256_Init(&ctx); SHA256_Update(&ctx, in, len); SHA256_Final(digest, &ctx); } /** * HMAC_SHA256_Init(ctx, K, Klen): * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from * ${K}. */ void HMAC_SHA256_Init(HMAC_SHA256_CTX * ctx, const void * _K, size_t Klen) { uint8_t pad[64]; uint8_t khash[32]; const uint8_t * K = _K; size_t i; /* If Klen > 64, the key is really SHA256(K). */ if (Klen > 64) { SHA256_Init(&ctx->ictx); SHA256_Update(&ctx->ictx, K, Klen); SHA256_Final(khash, &ctx->ictx); K = khash; Klen = 32; } /* Inner SHA256 operation is SHA256(K xor [block of 0x36] || data). */ SHA256_Init(&ctx->ictx); memset(pad, 0x36, 64); for (i = 0; i < Klen; i++) pad[i] ^= K[i]; SHA256_Update(&ctx->ictx, pad, 64); /* Outer SHA256 operation is SHA256(K xor [block of 0x5c] || hash). */ SHA256_Init(&ctx->octx); memset(pad, 0x5c, 64); for (i = 0; i < Klen; i++) pad[i] ^= K[i]; SHA256_Update(&ctx->octx, pad, 64); /* Clean the stack. */ insecure_memzero(khash, 32); insecure_memzero(pad, 64); } /** * HMAC_SHA256_Update(ctx, in, len): * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. */ void HMAC_SHA256_Update(HMAC_SHA256_CTX * ctx, const void * in, size_t len) { /* Feed data to the inner SHA256 operation. */ SHA256_Update(&ctx->ictx, in, len); } /** * HMAC_SHA256_Final(digest, ctx): * Output the HMAC-SHA256 of the data input to the context ${ctx} into the * buffer ${digest}. */ void HMAC_SHA256_Final(uint8_t digest[32], HMAC_SHA256_CTX * ctx) { uint8_t ihash[32]; /* Finish the inner SHA256 operation. */ SHA256_Final(ihash, &ctx->ictx); /* Feed the inner hash to the outer SHA256 operation. */ SHA256_Update(&ctx->octx, ihash, 32); /* Finish the outer SHA256 operation. */ SHA256_Final(digest, &ctx->octx); /* Clean the stack. */ insecure_memzero(ihash, 32); } /** * HMAC_SHA256_Buf(K, Klen, in, len, digest): * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of * length ${Klen}, and write the result to ${digest}. */ void HMAC_SHA256_Buf(const void * K, size_t Klen, const void * in, size_t len, uint8_t digest[32]) { HMAC_SHA256_CTX ctx; HMAC_SHA256_Init(&ctx, K, Klen); HMAC_SHA256_Update(&ctx, in, len); HMAC_SHA256_Final(digest, &ctx); } /** * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). */ void PBKDF2_SHA256(const uint8_t * passwd, size_t passwdlen, const uint8_t * salt, size_t saltlen, uint64_t c, uint8_t * buf, size_t dkLen) { HMAC_SHA256_CTX PShctx, hctx; size_t i; uint8_t ivec[4]; uint8_t U[32]; uint8_t T[32]; uint64_t j; int k; size_t clen; /* Sanity-check. */ assert(dkLen <= 32 * (size_t)(UINT32_MAX)); /* Compute HMAC state after processing P and S. */ HMAC_SHA256_Init(&PShctx, passwd, passwdlen); HMAC_SHA256_Update(&PShctx, salt, saltlen); /* Iterate through the blocks. */ for (i = 0; i * 32 < dkLen; i++) { /* Generate INT(i + 1). */ be32enc(ivec, (uint32_t)(i + 1)); /* Compute U_1 = PRF(P, S || INT(i)). */ memcpy(&hctx, &PShctx, sizeof(HMAC_SHA256_CTX)); HMAC_SHA256_Update(&hctx, ivec, 4); HMAC_SHA256_Final(U, &hctx); /* T_i = U_1 ... */ memcpy(T, U, 32); for (j = 2; j <= c; j++) { /* Compute U_j. */ HMAC_SHA256_Init(&hctx, passwd, passwdlen); HMAC_SHA256_Update(&hctx, U, 32); HMAC_SHA256_Final(U, &hctx); /* ... xor U_j ... */ for (k = 0; k < 32; k++) T[k] ^= U[k]; } /* Copy as many bytes as necessary into buf. */ clen = dkLen - i * 32; if (clen > 32) clen = 32; memcpy(&buf[i * 32], T, clen); } /* Clean PShctx, since we never called _Final on it. */ insecure_memzero(&PShctx, sizeof(HMAC_SHA256_CTX)); } scrypt-0.8.0/scrypt-1.2.0/libcperciva/alg/sha256.h0000644000076500000240000000532312561447061022012 0ustar mhallinstaff00000000000000#ifndef _SHA256_H_ #define _SHA256_H_ #include #include /* * Use #defines in order to avoid namespace collisions with anyone else's * SHA256 code (e.g., the code in OpenSSL). */ #define SHA256_Init libcperciva_SHA256_Init #define SHA256_Update libcperciva_SHA256_Update #define SHA256_Final libcperciva_SHA256_Final #define SHA256_Buf libcperciva_SHA256_Buf #define SHA256_CTX libcperciva_SHA256_CTX #define HMAC_SHA256_Init libcperciva_HMAC_SHA256_Init #define HMAC_SHA256_Update libcperciva_HMAC_SHA256_Update #define HMAC_SHA256_Final libcperciva_HMAC_SHA256_Final #define HMAC_SHA256_Buf libcperciva_HMAC_SHA256_Buf #define HMAC_SHA256_CTX libcperciva_HMAC_SHA256_CTX /* Context structure for SHA256 operations. */ typedef struct { uint32_t state[8]; uint64_t count; uint8_t buf[64]; } SHA256_CTX; /** * SHA256_Init(ctx): * Initialize the SHA256 context ${ctx}. */ void SHA256_Init(SHA256_CTX *); /** * SHA256_Update(ctx, in, len): * Input ${len} bytes from ${in} into the SHA256 context ${ctx}. */ void SHA256_Update(SHA256_CTX *, const void *, size_t); /** * SHA256_Final(digest, ctx): * Output the SHA256 hash of the data input to the context ${ctx} into the * buffer ${digest}. */ void SHA256_Final(uint8_t[32], SHA256_CTX *); /** * SHA256_Buf(in, len, digest): * Compute the SHA256 hash of ${len} bytes from $in} and write it to ${digest}. */ void SHA256_Buf(const void *, size_t, uint8_t[32]); /* Context structure for HMAC-SHA256 operations. */ typedef struct { SHA256_CTX ictx; SHA256_CTX octx; } HMAC_SHA256_CTX; /** * HMAC_SHA256_Init(ctx, K, Klen): * Initialize the HMAC-SHA256 context ${ctx} with ${Klen} bytes of key from * ${K}. */ void HMAC_SHA256_Init(HMAC_SHA256_CTX *, const void *, size_t); /** * HMAC_SHA256_Update(ctx, in, len): * Input ${len} bytes from ${in} into the HMAC-SHA256 context ${ctx}. */ void HMAC_SHA256_Update(HMAC_SHA256_CTX *, const void *, size_t); /** * HMAC_SHA256_Final(digest, ctx): * Output the HMAC-SHA256 of the data input to the context ${ctx} into the * buffer ${digest}. */ void HMAC_SHA256_Final(uint8_t[32], HMAC_SHA256_CTX *); /** * HMAC_SHA256_Buf(K, Klen, in, len, digest): * Compute the HMAC-SHA256 of ${len} bytes from ${in} using the key ${K} of * length ${Klen}, and write the result to ${digest}. */ void HMAC_SHA256_Buf(const void *, size_t, const void *, size_t, uint8_t[32]); /** * PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). */ void PBKDF2_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, uint8_t *, size_t); #endif /* !_SHA256_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/cpusupport/0000755000076500000240000000000012767242550022313 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h0000644000076500000240000000477412561447061024720 0ustar mhallinstaff00000000000000#ifndef _CPUSUPPORT_H_ #define _CPUSUPPORT_H_ /* * To enable support for non-portable CPU features at compile time, one or * more CPUSUPPORT_ARCH_FEATURE macros should be defined. This can be done * directly on the compiler command line; or a file can be created with the * necessary #define lines and then -D CPUSUPPORT_CONFIG_FILE=cpuconfig.h * (or similar) can be provided to include that file here. */ #ifdef CPUSUPPORT_CONFIG_FILE #include CPUSUPPORT_CONFIG_FILE #endif /* * The CPUSUPPORT_FEATURE macro declares the necessary variables and * functions for detecting CPU feature support at run time. The function * defined in the macro acts to cache the result of the ..._detect function * using the ..._present and ..._init variables. */ #define CPUSUPPORT_FEATURE(arch, feature) \ extern int cpusupport_ ## arch ## _ ## feature ## _present; \ extern int cpusupport_ ## arch ## _ ## feature ## _init; \ int cpusupport_ ## arch ## _ ## feature ## _detect(void); \ \ static inline int \ cpusupport_ ## arch ## _ ## feature(void) \ { \ \ if (cpusupport_ ## arch ## _ ## feature ## _present) \ return (1); \ else if (cpusupport_ ## arch ## _ ## feature ## _init) \ return (0); \ cpusupport_ ## arch ## _ ## feature ## _present = \ cpusupport_ ## arch ##_ ## feature ## _detect(); \ cpusupport_ ## arch ## _ ## feature ## _init = 1; \ return (cpusupport_ ## arch ## _ ## feature ## _present); \ } \ struct cpusupport_ ## arch ## _ ## feature ## _dummy /* * CPUSUPPORT_FEATURE_DECL(arch, feature): * Macro which defines variables and provides a function declaration for * detecting the presence of "feature" on the "arch" architecture. The * function body following this macro expansion must return nonzero if the * feature is present, or zero if the feature is not present or the detection * fails for any reason. */ #define CPUSUPPORT_FEATURE_DECL(arch, feature) \ int cpusupport_ ## arch ## _ ## feature ## _present = 0; \ int cpusupport_ ## arch ## _ ## feature ## _init = 0; \ int \ cpusupport_ ## arch ## _ ## feature ## _detect(void) /* * Any features listed here must have associated C files compiled and linked * in, since the macro references symbols which must be defined. Projects * which do not need to detect certain CPU features may wish to remove lines * from this list so that the associated C files can be omitted. */ CPUSUPPORT_FEATURE(x86, aesni); CPUSUPPORT_FEATURE(x86, sse2); #endif /* !_CPUSUPPORT_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/0000755000076500000240000000000012767242550021407 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_aes.c0000644000076500000240000000715712561447061023731 0ustar mhallinstaff00000000000000#include #include #include #include #include #include "cpusupport.h" #include "crypto_aes_aesni.h" #include "insecure_memzero.h" #include "warnp.h" #include "crypto_aes.h" /** * This represents either an AES_KEY or a struct crypto_aes_key_aesni; we * know which it is based on whether we're using AESNI code or not. As such, * it's just an opaque pointer; but declaring it as a named structure type * prevents type-mismatch bugs in upstream code. */ struct crypto_aes_key; #ifdef CPUSUPPORT_X86_AESNI /* Test whether OpenSSL and AESNI code produce the same AES ciphertext. */ static int aesnitest(uint8_t ptext[16], uint8_t * key, size_t keylen) { AES_KEY kexp_openssl; void * kexp_aesni; uint8_t ctext_openssl[16]; uint8_t ctext_aesni[16]; /* Expand the key. */ AES_set_encrypt_key(key, keylen * 8, &kexp_openssl); if ((kexp_aesni = crypto_aes_key_expand_aesni(key, keylen)) == NULL) goto err0; /* Encrypt the block. */ AES_encrypt(ptext, ctext_openssl, &kexp_openssl); crypto_aes_encrypt_block_aesni(ptext, ctext_aesni, kexp_aesni); /* Free the AESNI expanded key. */ crypto_aes_key_free_aesni(kexp_aesni); /* Do the outputs match? */ return (memcmp(ctext_openssl, ctext_aesni, 16)); err0: /* Failure! */ return (-1); } /* Should we use AESNI? */ static int useaesni(void) { static int aesnigood = -1; uint8_t key[32]; uint8_t ptext[16]; size_t i; /* If we haven't decided which code to use yet, decide now. */ while (aesnigood == -1) { /* Default to OpenSSL. */ aesnigood = 0; /* If the CPU doesn't claim to support AESNI, stop here. */ if (!cpusupport_x86_aesni()) break; /* Test cases: key is 0x00010203..., ptext is 0x00112233... */ for (i = 0; i < 16; i++) ptext[i] = 0x11 * i; for (i = 0; i < 32; i++) key[i] = i; /* Test that AESNI and OpenSSL produce the same results. */ if (aesnitest(ptext, key, 16) || aesnitest(ptext, key, 32)) { warn0("Disabling AESNI due to failed self-test"); break; } /* AESNI works; use it. */ aesnigood = 1; } return (aesnigood); } #endif /* CPUSUPPORT_X86_AESNI */ /** * crypto_aes_key_expand(key, len): * Expand the ${len}-byte AES key ${key} into a structure which can be passed * to crypto_aes_encrypt_block. The length must be 16 or 32. */ struct crypto_aes_key * crypto_aes_key_expand(const uint8_t * key, size_t len) { AES_KEY * kexp; /* Sanity-check. */ assert((len == 16) || (len == 32)); #ifdef CPUSUPPORT_X86_AESNI /* Use AESNI if we can. */ if (useaesni()) return (crypto_aes_key_expand_aesni(key, len)); #endif /* Allocate structure. */ if ((kexp = malloc(sizeof(AES_KEY))) == NULL) goto err0; /* Expand the key. */ AES_set_encrypt_key(key, len * 8, kexp); /* Success! */ return ((void *)kexp); err0: /* Failure! */ return (NULL); } /** * crypto_aes_encrypt_block(in, out, key): * Using the expanded AES key ${key}, encrypt the block ${in} and write the * resulting ciphertext to ${out}. */ void crypto_aes_encrypt_block(const uint8_t * in, uint8_t * out, const struct crypto_aes_key * key) { #ifdef CPUSUPPORT_X86_AESNI if (useaesni()) { crypto_aes_encrypt_block_aesni(in, out, (const void *)key); return; } #endif /* Get AES to do the work. */ AES_encrypt(in, out, (const void *)key); } /** * crypto_aes_key_free(key): * Free the expanded AES key ${key}. */ void crypto_aes_key_free(struct crypto_aes_key * key) { #ifdef CPUSUPPORT_X86_AESNI if (useaesni()) { crypto_aes_key_free_aesni((void *)key); return; } #endif /* Attempt to zero the expanded key. */ insecure_memzero(key, sizeof(AES_KEY)); /* Free the key. */ free(key); } scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_aes.h0000644000076500000240000000144512561447061023730 0ustar mhallinstaff00000000000000#ifndef _CRYPTO_AES_H_ #define _CRYPTO_AES_H_ #include #include /* Opaque structure. */ struct crypto_aes_key; /** * crypto_aes_key_expand(key, len): * Expand the ${len}-byte AES key ${key} into a structure which can be passed * to crypto_aes_encrypt_block. The length must be 16 or 32. */ struct crypto_aes_key * crypto_aes_key_expand(const uint8_t *, size_t); /** * crypto_aes_encrypt_block(in, out, key): * Using the expanded AES key ${key}, encrypt the block ${in} and write the * resulting ciphertext to ${out}. */ void crypto_aes_encrypt_block(const uint8_t *, uint8_t *, const struct crypto_aes_key *); /** * crypto_aes_key_free(key): * Free the expanded AES key ${key}. */ void crypto_aes_key_free(struct crypto_aes_key *); #endif /* !_CRYPTO_AES_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c0000644000076500000240000001725212561447061025105 0ustar mhallinstaff00000000000000#include "cpusupport.h" #ifdef CPUSUPPORT_X86_AESNI #include #include #include #include #include "insecure_memzero.h" #include "warnp.h" #include "crypto_aes_aesni.h" /* Expanded-key structure. */ struct crypto_aes_key_aesni { uint8_t rkeys_buf[15 * sizeof(__m128i) + (sizeof(__m128i) - 1)]; __m128i * rkeys; size_t nr; }; /* Compute an AES-128 round key. */ #define MKRKEY128(rkeys, i, rcon) do { \ __m128i _s = rkeys[i - 1]; \ __m128i _t = rkeys[i - 1]; \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \ _t = _mm_aeskeygenassist_si128(_t, rcon); \ _t = _mm_shuffle_epi32(_t, 0xff); \ rkeys[i] = _mm_xor_si128(_s, _t); \ } while (0) /** * crypto_aes_key_expand_128_aesni(key, rkeys): * Expand the 128-bit AES key ${key} into the 11 round keys ${rkeys}. This * implementation uses x86 AESNI instructions, and should only be used if * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. */ static void crypto_aes_key_expand_128_aesni(const uint8_t key[16], __m128i rkeys[11]) { /* The first round key is just the key. */ /** * XXX Compiler breakage: * The intrinsic defined by Intel for _mm_loadu_si128 defines it as * taking a (const __m128i *) parameter. This forces us to write a * bug: The cast to (const __m128i *) is invalid since it increases * the alignment requirement of the pointer. Alas, until compilers * get fixed intrinsics, all we can do is code the bug and require * that alignment-requirement-increasing compiler warnings get * disabled. */ rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]); /* * Each of the remaining round keys are computed from the preceding * round key: rotword+subword+rcon (provided as aeskeygenassist) to * compute the 'temp' value, then xor with 1, 2, 3, or all 4 of the * 32-bit words from the preceding round key. Unfortunately, 'rcon' * is encoded as an immediate value, so we need to write the loop out * ourselves rather than allowing the compiler to expand it. */ MKRKEY128(rkeys, 1, 0x01); MKRKEY128(rkeys, 2, 0x02); MKRKEY128(rkeys, 3, 0x04); MKRKEY128(rkeys, 4, 0x08); MKRKEY128(rkeys, 5, 0x10); MKRKEY128(rkeys, 6, 0x20); MKRKEY128(rkeys, 7, 0x40); MKRKEY128(rkeys, 8, 0x80); MKRKEY128(rkeys, 9, 0x1b); MKRKEY128(rkeys, 10, 0x36); } /* Compute an AES-256 round key. */ #define MKRKEY256(rkeys, i, shuffle, rcon) do { \ __m128i _s = rkeys[i - 2]; \ __m128i _t = rkeys[i - 1]; \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 4)); \ _s = _mm_xor_si128(_s, _mm_slli_si128(_s, 8)); \ _t = _mm_aeskeygenassist_si128(_t, rcon); \ _t = _mm_shuffle_epi32(_t, shuffle); \ rkeys[i] = _mm_xor_si128(_s, _t); \ } while (0) /** * crypto_aes_key_expand_256_aesni(key, rkeys): * Expand the 256-bit AES key ${key} into the 15 round keys ${rkeys}. This * implementation uses x86 AESNI instructions, and should only be used if * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. */ static void crypto_aes_key_expand_256_aesni(const uint8_t key[32], __m128i rkeys[15]) { /* The first two round keys are just the key. */ /** * XXX Compiler breakage: * The intrinsic defined by Intel for _mm_loadu_si128 defines it as * taking a (const __m128i *) parameter. This forces us to write a * bug: The cast to (const __m128i *) is invalid since it increases * the alignment requirement of the pointer. Alas, until compilers * get fixed intrinsics, all we can do is code the bug and require * that alignment-requirement-increasing compiler warnings get * disabled. */ rkeys[0] = _mm_loadu_si128((const __m128i *)&key[0]); rkeys[1] = _mm_loadu_si128((const __m128i *)&key[16]); /* * Each of the remaining round keys are computed from the preceding * pair of keys. Even rounds use rotword+subword+rcon, while odd * rounds just use subword; the aeskeygenassist instruction computes * both, and we use 0xff or 0xaa to select the one we need. The rcon * value used is irrelevant for odd rounds since we ignore the value * which it feeds into. Unfortunately, the 'shuffle' and 'rcon' * values are encoded into the instructions as immediates, so we need * to write the loop out ourselves rather than allowing the compiler * to expand it. */ MKRKEY256(rkeys, 2, 0xff, 0x01); MKRKEY256(rkeys, 3, 0xaa, 0x00); MKRKEY256(rkeys, 4, 0xff, 0x02); MKRKEY256(rkeys, 5, 0xaa, 0x00); MKRKEY256(rkeys, 6, 0xff, 0x04); MKRKEY256(rkeys, 7, 0xaa, 0x00); MKRKEY256(rkeys, 8, 0xff, 0x08); MKRKEY256(rkeys, 9, 0xaa, 0x00); MKRKEY256(rkeys, 10, 0xff, 0x10); MKRKEY256(rkeys, 11, 0xaa, 0x00); MKRKEY256(rkeys, 12, 0xff, 0x20); MKRKEY256(rkeys, 13, 0xaa, 0x00); MKRKEY256(rkeys, 14, 0xff, 0x40); } /** * crypto_aes_key_expand_aesni(key, len): * Expand the ${len}-byte AES key ${key} into a structure which can be passed * to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This * implementation uses x86 AESNI instructions, and should only be used if * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. */ void * crypto_aes_key_expand_aesni(const uint8_t * key, size_t len) { struct crypto_aes_key_aesni * kexp; size_t rkey_offset; /* Allocate structure. */ if ((kexp = malloc(sizeof(struct crypto_aes_key_aesni))) == NULL) goto err0; /* Figure out where to put the round keys. */ rkey_offset = (uintptr_t)(&kexp->rkeys_buf[0]) % sizeof(__m128i); rkey_offset = (sizeof(__m128i) - rkey_offset) % sizeof(__m128i); kexp->rkeys = (void *)&kexp->rkeys_buf[rkey_offset]; /* Compute round keys. */ if (len == 16) { kexp->nr = 10; crypto_aes_key_expand_128_aesni(key, kexp->rkeys); } else if (len == 32) { kexp->nr = 14; crypto_aes_key_expand_256_aesni(key, kexp->rkeys); } else { warn0("Unsupported AES key length: %zu bytes", len); goto err1; } /* Success! */ return (kexp); err1: free(kexp); err0: /* Failure! */ return (NULL); } /** * crypto_aes_encrypt_block_aesni(in, out, key): * Using the expanded AES key ${key}, encrypt the block ${in} and write the * resulting ciphertext to ${out}. This implementation uses x86 AESNI * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined * and cpusupport_x86_aesni() returns nonzero. */ void crypto_aes_encrypt_block_aesni(const uint8_t * in, uint8_t * out, const void * key) { const struct crypto_aes_key_aesni * _key = key; const __m128i * aes_key = _key->rkeys; __m128i aes_state; size_t nr = _key->nr; aes_state = _mm_loadu_si128((const __m128i *)in); aes_state = _mm_xor_si128(aes_state, aes_key[0]); aes_state = _mm_aesenc_si128(aes_state, aes_key[1]); aes_state = _mm_aesenc_si128(aes_state, aes_key[2]); aes_state = _mm_aesenc_si128(aes_state, aes_key[3]); aes_state = _mm_aesenc_si128(aes_state, aes_key[4]); aes_state = _mm_aesenc_si128(aes_state, aes_key[5]); aes_state = _mm_aesenc_si128(aes_state, aes_key[6]); aes_state = _mm_aesenc_si128(aes_state, aes_key[7]); aes_state = _mm_aesenc_si128(aes_state, aes_key[8]); aes_state = _mm_aesenc_si128(aes_state, aes_key[9]); if (nr > 10) { aes_state = _mm_aesenc_si128(aes_state, aes_key[10]); aes_state = _mm_aesenc_si128(aes_state, aes_key[11]); if (nr > 12) { aes_state = _mm_aesenc_si128(aes_state, aes_key[12]); aes_state = _mm_aesenc_si128(aes_state, aes_key[13]); } } aes_state = _mm_aesenclast_si128(aes_state, aes_key[nr]); _mm_storeu_si128((__m128i *)out, aes_state); } /** * crypto_aes_key_free_aesni(key): * Free the expanded AES key ${key}. */ void crypto_aes_key_free_aesni(void * key) { /* Attempt to zero the expanded key. */ insecure_memzero(key, sizeof(struct crypto_aes_key_aesni)); /* Free the key. */ free(key); } #endif /* CPUSUPPORT_X86_AESNI */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h0000644000076500000240000000207012561447061025102 0ustar mhallinstaff00000000000000#ifndef _CRYPTO_AES_AESNI_H_ #define _CRYPTO_AES_AESNI_H_ #include #include /** * crypto_aes_key_expand_aesni(key, len): * Expand the ${len}-byte AES key ${key} into a structure which can be passed * to crypto_aes_encrypt_block_aesni. The length must be 16 or 32. This * implementation uses x86 AESNI instructions, and should only be used if * CPUSUPPORT_X86_AESNI is defined and cpusupport_x86_aesni() returns nonzero. */ void * crypto_aes_key_expand_aesni(const uint8_t *, size_t); /** * crypto_aes_encrypt_block_aesni(in, out, key): * Using the expanded AES key ${key}, encrypt the block ${in} and write the * resulting ciphertext to ${out}. This implementation uses x86 AESNI * instructions, and should only be used if CPUSUPPORT_X86_AESNI is defined * and cpusupport_x86_aesni() returns nonzero. */ void crypto_aes_encrypt_block_aesni(const uint8_t *, uint8_t *, const void *); /** * crypto_aes_key_free_aesni(key): * Free the expanded AES key ${key}. */ void crypto_aes_key_free_aesni(void *); #endif /* !_CRYPTO_AES_AESNI_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c0000644000076500000240000000543512561447061024437 0ustar mhallinstaff00000000000000#include #include #include "crypto_aes.h" #include "sysendian.h" #include "crypto_aesctr.h" struct crypto_aesctr { const struct crypto_aes_key * key; uint64_t nonce; uint64_t bytectr; uint8_t buf[16]; }; /** * crypto_aesctr_init(key, nonce): * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided * expanded key and nonce. The key provided must remain valid for the * lifetime of the stream. */ struct crypto_aesctr * crypto_aesctr_init(const struct crypto_aes_key * key, uint64_t nonce) { struct crypto_aesctr * stream; /* Allocate memory. */ if ((stream = malloc(sizeof(struct crypto_aesctr))) == NULL) goto err0; /* Initialize values. */ stream->key = key; stream->nonce = nonce; stream->bytectr = 0; /* Success! */ return (stream); err0: /* Failure! */ return (NULL); } /** * crypto_aesctr_stream(stream, inbuf, outbuf, buflen): * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with * bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers * ${inbuf} and ${outbuf} overlap, they must be identical. */ void crypto_aesctr_stream(struct crypto_aesctr * stream, const uint8_t * inbuf, uint8_t * outbuf, size_t buflen) { uint8_t pblk[16]; size_t pos; int bytemod; for (pos = 0; pos < buflen; pos++) { /* How far through the buffer are we? */ bytemod = stream->bytectr % 16; /* Generate a block of cipherstream if needed. */ if (bytemod == 0) { be64enc(pblk, stream->nonce); be64enc(pblk + 8, stream->bytectr / 16); crypto_aes_encrypt_block(pblk, stream->buf, stream->key); } /* Encrypt a byte. */ outbuf[pos] = inbuf[pos] ^ stream->buf[bytemod]; /* Move to the next byte of cipherstream. */ stream->bytectr += 1; } } /** * crypto_aesctr_free(stream): * Free the provided stream object. */ void crypto_aesctr_free(struct crypto_aesctr * stream) { int i; /* Be compatible with free(NULL). */ if (stream == NULL) return; /* Zero potentially sensitive information. */ for (i = 0; i < 16; i++) stream->buf[i] = 0; stream->bytectr = stream->nonce = 0; /* Free the stream. */ free(stream); } /** * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen): * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free. */ void crypto_aesctr_buf(const struct crypto_aes_key * key, uint64_t nonce, const uint8_t * inbuf, uint8_t * outbuf, size_t buflen) { struct crypto_aesctr stream_rec; struct crypto_aesctr * stream = &stream_rec; int i; /* Initialize values. */ stream->key = key; stream->nonce = nonce; stream->bytectr = 0; /* Perform the encryption. */ crypto_aesctr_stream(stream, inbuf, outbuf, buflen); /* Zero potentially sensitive information. */ for (i = 0; i < 16; i++) stream->buf[i] = 0; stream->bytectr = stream->nonce = 0; } scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h0000644000076500000240000000227212561447061024440 0ustar mhallinstaff00000000000000#ifndef _CRYPTO_AESCTR_H_ #define _CRYPTO_AESCTR_H_ #include #include /* Opaque type. */ struct crypto_aes_key; /** * crypto_aesctr_init(key, nonce): * Prepare to encrypt/decrypt data with AES in CTR mode, using the provided * expanded key and nonce. The key provided must remain valid for the * lifetime of the stream. */ struct crypto_aesctr * crypto_aesctr_init(const struct crypto_aes_key *, uint64_t); /** * crypto_aesctr_stream(stream, inbuf, outbuf, buflen): * Generate the next ${buflen} bytes of the AES-CTR stream and xor them with * bytes from ${inbuf}, writing the result into ${outbuf}. If the buffers * ${inbuf} and ${outbuf} overlap, they must be identical. */ void crypto_aesctr_stream(struct crypto_aesctr *, const uint8_t *, uint8_t *, size_t); /** * crypto_aesctr_free(stream): * Free the provided stream object. */ void crypto_aesctr_free(struct crypto_aesctr *); /** * crypto_aesctr_buf(key, nonce, inbuf, outbuf, buflen): * Equivalent to init(key, nonce); stream(inbuf, outbuf, buflen); free. */ void crypto_aesctr_buf(const struct crypto_aes_key *, uint64_t, const uint8_t *, uint8_t *, size_t); #endif /* !_CRYPTO_AESCTR_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c0000644000076500000240000001135312561447061024652 0ustar mhallinstaff00000000000000#include #include #include #include "entropy.h" #include "insecure_memzero.h" #include "sha256.h" #include "crypto_entropy.h" /** * This system implements the HMAC_DRBG pseudo-random number generator as * specified in section 10.1.2 of the NIST SP 800-90 standard. In this * implementation, the optional personalization_string and additional_input * specified in the standard are not implemented. */ /* Internal HMAC_DRBG state. */ static struct { uint8_t Key[32]; uint8_t V[32]; uint32_t reseed_counter; } drbg; /* Set to non-zero once the PRNG has been instantiated. */ static int instantiated = 0; /* Could be as high as 2^48 if we wanted... */ #define RESEED_INTERVAL 256 /* Limited to 2^16 by specification. */ #define GENERATE_MAXLEN 65536 static int instantiate(void); static void update(uint8_t *, size_t); static int reseed(void); static void generate(uint8_t *, size_t); /** * instantiate(void): * Initialize the DRBG state. (Section 10.1.2.3) */ static int instantiate(void) { uint8_t seed_material[48]; /* Obtain random seed_material = (entropy_input || nonce). */ if (entropy_read(seed_material, 48)) return (-1); /* Initialize Key, V, and reseed_counter. */ memset(drbg.Key, 0x00, 32); memset(drbg.V, 0x01, 32); drbg.reseed_counter = 1; /* Mix the random seed into the state. */ update(seed_material, 48); /* Clean the stack. */ insecure_memzero(seed_material, 48); /* Success! */ return (0); } /** * update(data, datalen): * Update the DRBG state using the provided data. (Section 10.1.2.2) */ static void update(uint8_t * data, size_t datalen) { HMAC_SHA256_CTX ctx; uint8_t K[32]; uint8_t Vx[33]; /* Load (Key, V) into (K, Vx). */ memcpy(K, drbg.Key, 32); memcpy(Vx, drbg.V, 32); /* K <- HMAC(K, V || 0x00 || data). */ Vx[32] = 0x00; HMAC_SHA256_Init(&ctx, K, 32); HMAC_SHA256_Update(&ctx, Vx, 33); HMAC_SHA256_Update(&ctx, data, datalen); HMAC_SHA256_Final(K, &ctx); /* V <- HMAC(K, V). */ HMAC_SHA256_Buf(K, 32, Vx, 32, Vx); /* If the provided data is non-Null, perform another mixing stage. */ if (datalen != 0) { /* K <- HMAC(K, V || 0x01 || data). */ Vx[32] = 0x01; HMAC_SHA256_Init(&ctx, K, 32); HMAC_SHA256_Update(&ctx, Vx, 33); HMAC_SHA256_Update(&ctx, data, datalen); HMAC_SHA256_Final(K, &ctx); /* V <- HMAC(K, V). */ HMAC_SHA256_Buf(K, 32, Vx, 32, Vx); } /* Copy (K, Vx) back to (Key, V). */ memcpy(drbg.Key, K, 32); memcpy(drbg.V, Vx, 32); /* Clean the stack. */ insecure_memzero(K, 32); insecure_memzero(Vx, 33); } /** * reseed(void): * Reseed the DRBG state (mix in new entropy). (Section 10.1.2.4) */ static int reseed(void) { uint8_t seed_material[32]; /* Obtain random seed_material = entropy_input. */ if (entropy_read(seed_material, 32)) return (-1); /* Mix the random seed into the state. */ update(seed_material, 32); /* Reset the reseed_counter. */ drbg.reseed_counter = 1; /* Clean the stack. */ insecure_memzero(seed_material, 32); /* Success! */ return (0); } /** * generate(buf, buflen): * Fill the provided buffer with random bits, assuming that reseed_counter * is less than RESEED_INTERVAL (the caller is responsible for calling * reseed() as needed) and ${buflen} is less than 2^16 (the caller is * responsible for splitting up larger requests). (Section 10.1.2.5) */ static void generate(uint8_t * buf, size_t buflen) { size_t bufpos; assert(buflen <= GENERATE_MAXLEN); assert(drbg.reseed_counter <= RESEED_INTERVAL); /* Iterate until we've filled the buffer. */ for (bufpos = 0; bufpos < buflen; bufpos += 32) { HMAC_SHA256_Buf(drbg.Key, 32, drbg.V, 32, drbg.V); if (buflen - bufpos >= 32) memcpy(&buf[bufpos], drbg.V, 32); else memcpy(&buf[bufpos], drbg.V, buflen - bufpos); } /* Mix up state. */ update(NULL, 0); /* We're one data-generation step closer to needing a reseed. */ drbg.reseed_counter += 1; } /** * crypto_entropy_read(buf, buflen): * Fill the buffer with unpredictable bits. */ int crypto_entropy_read(uint8_t * buf, size_t buflen) { size_t bytes_to_provide; /* Instantiate if needed. */ if (instantiated == 0) { /* Try to instantiate the PRNG. */ if (instantiate()) return (-1); /* We have instantiated the PRNG. */ instantiated = 1; } /* Loop until we've filled the buffer. */ while (buflen > 0) { /* Do we need to reseed? */ if (drbg.reseed_counter > RESEED_INTERVAL) { if (reseed()) return (-1); } /* How much data are we generating in this step? */ if (buflen > GENERATE_MAXLEN) bytes_to_provide = GENERATE_MAXLEN; else bytes_to_provide = buflen; /* Generate bytes. */ generate(buf, bytes_to_provide); /* We've done part of the buffer. */ buf += bytes_to_provide; buflen -= bytes_to_provide; } /* Success! */ return (0); } scrypt-0.8.0/scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h0000644000076500000240000000046712561447061024663 0ustar mhallinstaff00000000000000#ifndef _CRYPTO_ENTROPY_H_ #define _CRYPTO_ENTROPY_H_ #include #include /** * crypto_entropy_read(buf, buflen): * Fill the buffer with unpredictable bits. The value ${buflen} must be * less than 2^16. */ int crypto_entropy_read(uint8_t *, size_t); #endif /* !_CRYPTO_ENTROPY_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/0000755000076500000240000000000012767242550021044 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/entropy.c0000644000076500000240000000372212767237202022712 0ustar mhallinstaff00000000000000#include #include #include #include #include "warnp.h" #include "entropy.h" #ifdef _WIN32 #include #include #endif /** * XXX Portability * XXX We obtain random bytes from the operating system by opening * XXX /dev/urandom and reading them from that device; this works on * XXX modern UNIX-like operating systems but not on systems like * XXX win32 where there is no concept of /dev/urandom. */ /** * entropy_read(buf, buflen): * Fill the given buffer with random bytes provided by the operating system. */ int entropy_read(uint8_t * buf, size_t buflen) { int fd; ssize_t lenread; #ifndef _WIN32 /* Sanity-check the buffer size. */ if (buflen > SSIZE_MAX) { warn0("Programmer error: " "Trying to read insane amount of random data: %zu", buflen); goto err0; } /* Open /dev/urandom. */ if ((fd = open("/dev/urandom", O_RDONLY)) == -1) { warnp("open(/dev/urandom)"); goto err0; } /* Read bytes until we have filled the buffer. */ while (buflen > 0) { if ((lenread = read(fd, buf, buflen)) == -1) { warnp("read(/dev/urandom)"); goto err1; } /* The random device should never EOF. */ if (lenread == 0) { warn0("EOF on /dev/urandom?"); goto err1; } /* We've filled a portion of the buffer. */ buf += lenread; buflen -= lenread; } /* Close the device. */ while (close(fd) == -1) { if (errno != EINTR) { warnp("close(/dev/urandom)"); goto err0; } } /* Success! */ return (0); err1: close(fd); err0: /* Failure! */ return (-1); #else // _WIN32 HCRYPTPROV context; DWORD error; if(CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, 0) == NTE_BAD_KEYSET) { if(!CryptAcquireContext(&context, NULL, NULL, PROV_RSA_AES, CRYPT_NEWKEYSET)) { error = GetLastError(); return (-1); } } if(CryptGenRandom(context, 32, buf)) { buf += 32; return (0); } else{return(-1);} #endif // _WIN32 } scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/entropy.h0000644000076500000240000000040512561447061022710 0ustar mhallinstaff00000000000000#ifndef _ENTROPY_H_ #define _ENTROPY_H_ #include #include /** * entropy_read(buf, buflen): * Fill the given buffer with random bytes provided by the operating system. */ int entropy_read(uint8_t *, size_t); #endif /* !_ENTROPY_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/insecure_memzero.c0000644000076500000240000000062412561447061024561 0ustar mhallinstaff00000000000000#include #include #include "insecure_memzero.h" /* Function which does the zeroing. */ static void insecure_memzero_func(volatile void * buf, size_t len) { volatile uint8_t * _buf = buf; size_t i; for (i = 0; i < len; i++) _buf[i] = 0; } /* Pointer to memory-zeroing function. */ void (* volatile insecure_memzero_ptr)(volatile void *, size_t) = insecure_memzero_func; scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/insecure_memzero.h0000644000076500000240000000272412561447061024571 0ustar mhallinstaff00000000000000#ifndef _INSECURE_MEMZERO_H_ #define _INSECURE_MEMZERO_H_ #include /* Pointer to memory-zeroing function. */ extern void (* volatile insecure_memzero_ptr)(volatile void *, size_t); /** * insecure_memzero(buf, len): * Attempt to zero ${len} bytes at ${buf} in spite of optimizing compilers' * best (standards-compliant) attempts to remove the buffer-zeroing. In * particular, to avoid performing the zeroing, a compiler would need to * use optimistic devirtualization; recognize that non-volatile objects do not * need to be treated as volatile, even if they are accessed via volatile * qualified pointers; and perform link-time optimization; in addition to the * dead-code elimination which often causes buffer-zeroing to be elided. * * Note however that zeroing a buffer does not guarantee that the data held * in the buffer is not stored elsewhere; in particular, there may be copies * held in CPU registers or in anonymous allocations on the stack, even if * every named variable is successfully sanitized. Solving the "wipe data * from the system" problem will require a C language extension which does not * yet exist. * * For more information, see: * http://www.daemonology.net/blog/2014-09-04-how-to-zero-a-buffer.html * http://www.daemonology.net/blog/2014-09-06-zeroing-buffers-is-insufficient.html */ static inline void insecure_memzero(volatile void * buf, size_t len) { (insecure_memzero_ptr)(buf, len); } #endif /* !_INSECURE_MEMZERO_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/sysendian.h0000644000076500000240000000611312561447061023207 0ustar mhallinstaff00000000000000#ifndef _SYSENDIAN_H_ #define _SYSENDIAN_H_ #include /* Avoid namespace collisions with BSD . */ #define be16dec libcperciva_be16dec #define be16enc libcperciva_be16enc #define be32dec libcperciva_be32dec #define be32enc libcperciva_be32enc #define be64dec libcperciva_be64dec #define be64enc libcperciva_be64enc #define le16dec libcperciva_le16dec #define le16enc libcperciva_le16enc #define le32dec libcperciva_le32dec #define le32enc libcperciva_le32enc #define le64dec libcperciva_le64dec #define le64enc libcperciva_le64enc static inline uint16_t be16dec(const void * pp) { const uint8_t * p = (uint8_t const *)pp; return ((uint16_t)(p[1]) + ((uint16_t)(p[0]) << 8)); } static inline void be16enc(void * pp, uint16_t x) { uint8_t * p = (uint8_t *)pp; p[1] = x & 0xff; p[0] = (x >> 8) & 0xff; } static inline uint32_t be32dec(const void * pp) { const uint8_t * p = (uint8_t const *)pp; return ((uint32_t)(p[3]) + ((uint32_t)(p[2]) << 8) + ((uint32_t)(p[1]) << 16) + ((uint32_t)(p[0]) << 24)); } static inline void be32enc(void * pp, uint32_t x) { uint8_t * p = (uint8_t *)pp; p[3] = x & 0xff; p[2] = (x >> 8) & 0xff; p[1] = (x >> 16) & 0xff; p[0] = (x >> 24) & 0xff; } static inline uint64_t be64dec(const void * pp) { const uint8_t * p = (uint8_t const *)pp; return ((uint64_t)(p[7]) + ((uint64_t)(p[6]) << 8) + ((uint64_t)(p[5]) << 16) + ((uint64_t)(p[4]) << 24) + ((uint64_t)(p[3]) << 32) + ((uint64_t)(p[2]) << 40) + ((uint64_t)(p[1]) << 48) + ((uint64_t)(p[0]) << 56)); } static inline void be64enc(void * pp, uint64_t x) { uint8_t * p = (uint8_t *)pp; p[7] = x & 0xff; p[6] = (x >> 8) & 0xff; p[5] = (x >> 16) & 0xff; p[4] = (x >> 24) & 0xff; p[3] = (x >> 32) & 0xff; p[2] = (x >> 40) & 0xff; p[1] = (x >> 48) & 0xff; p[0] = (x >> 56) & 0xff; } static inline uint16_t le16dec(const void * pp) { const uint8_t * p = (uint8_t const *)pp; return ((uint16_t)(p[0]) + ((uint16_t)(p[1]) << 8)); } static inline void le16enc(void * pp, uint16_t x) { uint8_t * p = (uint8_t *)pp; p[0] = x & 0xff; p[1] = (x >> 8) & 0xff; } static inline uint32_t le32dec(const void * pp) { const uint8_t * p = (uint8_t const *)pp; return ((uint32_t)(p[0]) + ((uint32_t)(p[1]) << 8) + ((uint32_t)(p[2]) << 16) + ((uint32_t)(p[3]) << 24)); } static inline void le32enc(void * pp, uint32_t x) { uint8_t * p = (uint8_t *)pp; p[0] = x & 0xff; p[1] = (x >> 8) & 0xff; p[2] = (x >> 16) & 0xff; p[3] = (x >> 24) & 0xff; } static inline uint64_t le64dec(const void * pp) { const uint8_t * p = (uint8_t const *)pp; return ((uint64_t)(p[0]) + ((uint64_t)(p[1]) << 8) + ((uint64_t)(p[2]) << 16) + ((uint64_t)(p[3]) << 24) + ((uint64_t)(p[4]) << 32) + ((uint64_t)(p[5]) << 40) + ((uint64_t)(p[6]) << 48) + ((uint64_t)(p[7]) << 56)); } static inline void le64enc(void * pp, uint64_t x) { uint8_t * p = (uint8_t *)pp; p[0] = x & 0xff; p[1] = (x >> 8) & 0xff; p[2] = (x >> 16) & 0xff; p[3] = (x >> 24) & 0xff; p[4] = (x >> 32) & 0xff; p[5] = (x >> 40) & 0xff; p[6] = (x >> 48) & 0xff; p[7] = (x >> 56) & 0xff; } #endif /* !_SYSENDIAN_H_ */ scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/warnp.c0000644000076500000240000000247712561447061022345 0ustar mhallinstaff00000000000000#include #include #include #include #include #include "warnp.h" static int initialized = 0; static char * name = NULL; /* Free the name string. */ static void done(void) { free(name); name = NULL; } /** * warnp_setprogname(progname): * Set the program name to be used by warn() and warnx() to ${progname}. */ void warnp_setprogname(const char * progname) { const char * p; /* Free the name if we already have one. */ free(name); /* Find the last segment of the program name. */ for (p = progname; progname[0] != '\0'; progname++) if (progname[0] == '/') p = progname + 1; /* Copy the name string. */ name = strdup(p); /* If we haven't already done so, register our exit handler. */ if (initialized == 0) { atexit(done); initialized = 1; } } void warn(const char * fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)"); if (fmt != NULL) { fprintf(stderr, ": "); vfprintf(stderr, fmt, ap); } fprintf(stderr, ": %s\n", strerror(errno)); va_end(ap); } void warnx(const char * fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s", (name != NULL) ? name : "(unknown)"); if (fmt != NULL) { fprintf(stderr, ": "); vfprintf(stderr, fmt, ap); } fprintf(stderr, "\n"); va_end(ap); } scrypt-0.8.0/scrypt-1.2.0/libcperciva/util/warnp.h0000644000076500000240000000252512561447061022344 0ustar mhallinstaff00000000000000#ifndef _WARNP_H_ #define _WARNP_H_ #include /* Avoid namespace collisions with BSD . */ #define warn libcperciva_warn #define warnx libcperciva_warnx /** * warnp_setprogname(progname): * Set the program name to be used by warn() and warnx() to ${progname}. */ void warnp_setprogname(const char *); #define WARNP_INIT do { \ if (argv[0] != NULL) \ warnp_setprogname(argv[0]); \ } while (0) /* As in BSD . */ void warn(const char *, ...); void warnx(const char *, ...); /* * If compiled with DEBUG defined, print __FILE__ and __LINE__. */ #ifdef DEBUG #define warnline do { \ warnx("%s, %d", __FILE__, __LINE__); \ } while (0) #else #define warnline #endif /* * Call warn(3) or warnx(3) depending upon whether errno == 0; and clear * errno (so that the standard error message isn't repeated later). */ #define warnp(...) do { \ warnline; \ if (errno != 0) { \ warn(__VA_ARGS__); \ errno = 0; \ } else \ warnx(__VA_ARGS__); \ } while (0) /* * Call warnx(3) and set errno == 0. Unlike warnp, this should be used * in cases where we're reporting a problem which we discover ourselves * rather than one which is reported to us from a library or the kernel. */ #define warn0(...) do { \ warnline; \ warnx(__VA_ARGS__); \ errno = 0; \ } while (0) #endif /* !_WARNP_H_ */ scrypt-0.8.0/scrypt-1.2.0/scrypt_platform.h0000644000076500000240000000040712546200322021170 0ustar mhallinstaff00000000000000#ifndef _SCRYPT_PLATFORM_H_ #define _SCRYPT_PLATFORM_H_ #if defined(CONFIG_H_FILE) #include CONFIG_H_FILE #elif defined(HAVE_CONFIG_H) #include "config.h" #else #error Need either CONFIG_H_FILE or HAVE_CONFIG_H defined. #endif #endif /* !_SCRYPT_PLATFORM_H_ */ scrypt-0.8.0/scrypt.egg-info/0000755000076500000240000000000012767242550016642 5ustar mhallinstaff00000000000000scrypt-0.8.0/scrypt.egg-info/dependency_links.txt0000644000076500000240000000000112767242550022710 0ustar mhallinstaff00000000000000 scrypt-0.8.0/scrypt.egg-info/PKG-INFO0000644000076500000240000001361212767242550017742 0ustar mhallinstaff00000000000000Metadata-Version: 1.1 Name: scrypt Version: 0.8.0 Summary: Bindings for the scrypt key derivation function library Home-page: http://bitbucket.org/mhallin/py-scrypt Author: Magnus Hallin Author-email: mhallin@gmail.com License: 2-clause BSD Description: ========================= Python scrypt_ bindings ========================= This is a set of Python_ bindings for the scrypt_ key derivation function. Scrypt is useful when encrypting password as it is possible to specify a *minimum* amount of time to use when encrypting and decrypting. If, for example, a password takes 0.05 seconds to verify, a user won't notice the slight delay when signing in, but doing a brute force search of several billion passwords will take a considerable amount of time. This is in contrast to more traditional hash functions such as MD5 or the SHA family which can be implemented extremely fast on cheap hardware. Installation ============ You can install py-scrypt from this repository if you want the latest but possibly non-compiling version:: $ hg clone http://bitbucket.org/mhallin/py-scrypt $ cd py-scrypt $ python setup.py build Become superuser (or use virtualenv): # python setup.py install Run tests after install: $ python setup.py test Or you can install the latest release from PyPi:: $ pip install scrypt If you want py-scrypt for your Python 3 environment, just run the above commands with your Python 3 interpreter. Py-scrypt supports both Python 2 and 3. From version 0.6.0 (not available on PyPi yet), py-scrypt supports PyPy as well. Usage ===== Fore encryption/decryption, the library exports two functions ``encrypt`` and ``decrypt``:: >>> import scrypt >>> data = scrypt.encrypt('a secret message', 'password', maxtime=0.1) # This will take at least 0.1 seconds >>> data[:20] 'scrypt\x00\r\x00\x00\x00\x08\x00\x00\x00\x01RX9H' >>> scrypt.decrypt(data, 'password', maxtime=0.1) # This will also take at least 0.1 seconds 'a secret message' >>> scrypt.decrypt(data, 'password', maxtime=0.05) # scrypt won't be able to decrypt this data fast enough Traceback (most recent call last): File "", line 1, in scrypt.error: decrypting file would take too long >>> scrypt.decrypt(data, 'wrong password', maxtime=0.1) # scrypt will throw an exception if the password is incorrect Traceback (most recent call last): File "", line 1, in scrypt.error: password is incorrect From these, one can make a simple password verifier using the following functions:: def hash_password(password, maxtime=0.5, datalength=64): return scrypt.encrypt(os.urandom(datalength), password, maxtime=maxtime) def verify_password(hashed_password, guessed_password, maxtime=0.5): try: scrypt.decrypt(hashed_password, guessed_password, maxtime) return True except scrypt.error: return False But, if you want output that is deterministic and constant in size, you can use the ``hash`` function:: >>> import scrypt >>> h1 = scrypt.hash('password', 'random salt') >>> len(h1) # The hash will be 64 bytes by default, but is overridable. 64 >>> h1[:10] '\xfe\x87\xf3hS\tUo\xcd\xc8' >>> h2 = scrypt.hash('password', 'random salt') >>> h1 == h2 # The hash function is deterministic True Acknowledgements ================ Scrypt_ was created by Colin Percival and is licensed as 2-clause BSD. Since scrypt does not normally build as a shared library, I have included the source for the currently latest version of the library in this repository. When a new version arrives, I will update these sources. `Kelvin Wong`_ on Bitbucket provided changes to make the library available on Mac OS X 10.6 and earlier, as well as changes to make the library work more like the command-line version of scrypt by default. Kelvin also contributed with the unit tests, lots of cross platform testing and work on the ``hash`` function. Burstaholic_ on Bitbucket provided the necessary changes to make the library build on Windows. The `python-appveyor-demo`_ repository for setting up automated Windows builds for a multitude of Python versions. License ======= This library is licensed under the same license as scrypt; 2-clause BSD. .. _scrypt: http://www.tarsnap.com/scrypt.html .. _Python: http://python.org .. _Burstaholic: https://bitbucket.org/Burstaholic .. _Kelvin Wong: https://bitbucket.org/kelvinwong_ca .. _python-appveyor-demo: https://github.com/ogrisel/python-appveyor-demo Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Topic :: Security :: Cryptography Classifier: Topic :: Software Development :: Libraries scrypt-0.8.0/scrypt.egg-info/SOURCES.txt0000644000076500000240000000321512767242550020527 0ustar mhallinstaff00000000000000MANIFEST.in README.rst scrypt.py setup.py scrypt-1.2.0/config.h scrypt-1.2.0/scrypt_platform.h scrypt-1.2.0/lib/crypto/crypto_scrypt.c scrypt-1.2.0/lib/crypto/crypto_scrypt.h scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.h scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.h scrypt-1.2.0/lib/scryptenc/scryptenc.c scrypt-1.2.0/lib/scryptenc/scryptenc.h scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.h scrypt-1.2.0/lib/util/memlimit.c scrypt-1.2.0/lib/util/memlimit.h scrypt-1.2.0/libcperciva/alg/sha256.c scrypt-1.2.0/libcperciva/alg/sha256.h scrypt-1.2.0/libcperciva/cpusupport/cpusupport.h scrypt-1.2.0/libcperciva/crypto/crypto_aes.c scrypt-1.2.0/libcperciva/crypto/crypto_aes.h scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.h scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.h scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c scrypt-1.2.0/libcperciva/crypto/crypto_entropy.h scrypt-1.2.0/libcperciva/util/entropy.c scrypt-1.2.0/libcperciva/util/entropy.h scrypt-1.2.0/libcperciva/util/insecure_memzero.c scrypt-1.2.0/libcperciva/util/insecure_memzero.h scrypt-1.2.0/libcperciva/util/sysendian.h scrypt-1.2.0/libcperciva/util/warnp.c scrypt-1.2.0/libcperciva/util/warnp.h scrypt.egg-info/PKG-INFO scrypt.egg-info/SOURCES.txt scrypt.egg-info/dependency_links.txt scrypt.egg-info/top_level.txt src/scrypt.c tests/__init__.py tests/ciphertexts.csv tests/hashvectors.csv tests/test_scrypt.py tests/test_scrypt_py2x.py tests/test_scrypt_py3x.pyscrypt-0.8.0/scrypt.egg-info/top_level.txt0000644000076500000240000000001712767242550021372 0ustar mhallinstaff00000000000000_scrypt scrypt scrypt-0.8.0/scrypt.py0000644000076500000240000001713012546212120015505 0ustar mhallinstaff00000000000000import imp import os import sys from ctypes import (cdll, POINTER, pointer, c_char_p, c_size_t, c_double, c_int, c_uint64, c_uint32, create_string_buffer) _scrypt = cdll.LoadLibrary(imp.find_module('_scrypt')[1]) _scryptenc_buf = _scrypt.exp_scryptenc_buf _scryptenc_buf.argtypes = [c_char_p, # const uint_t *inbuf c_size_t, # size_t inbuflen c_char_p, # uint8_t *outbuf c_char_p, # const uint8_t *passwd c_size_t, # size_t passwdlen c_size_t, # size_t maxmem c_double, # double maxmemfrac c_double, # double maxtime ] _scryptenc_buf.restype = c_int _scryptdec_buf = _scrypt.exp_scryptdec_buf _scryptdec_buf.argtypes = [c_char_p, # const uint8_t *inbuf c_size_t, # size_t inbuflen c_char_p, # uint8_t *outbuf POINTER(c_size_t), # size_t *outlen c_char_p, # const uint8_t *passwd c_size_t, # size_t passwdlen c_size_t, # size_t maxmem c_double, # double maxmemfrac c_double, # double maxtime ] _scryptdec_buf.restype = c_int _crypto_scrypt = _scrypt.exp_crypto_scrypt _crypto_scrypt.argtypes = [c_char_p, # const uint8_t *passwd c_size_t, # size_t passwdlen c_char_p, # const uint8_t *salt c_size_t, # size_t saltlen c_uint64, # uint64_t N c_uint32, # uint32_t r c_uint32, # uint32_t p c_char_p, # uint8_t *buf c_size_t, # size_t buflen ] _crypto_scrypt.restype = c_int ERROR_MESSAGES = ['success', 'getrlimit or sysctl(hw.usermem) failed', 'clock_getres or clock_gettime failed', 'error computing derived key', 'could not read salt from /dev/urandom', 'error in OpenSSL', 'malloc failed', 'data is not a valid scrypt-encrypted block', 'unrecognized scrypt format', 'decrypting file would take too much memory', 'decrypting file would take too long', 'password is incorrect', 'error writing output file', 'error reading input file'] MAXMEM_DEFAULT = 0 MAXMEMFRAC_DEFAULT = 0.5 MAXTIME_DEFAULT = 300.0 MAXTIME_DEFAULT_ENC = 5.0 IS_PY2 = sys.version_info < (3, 0, 0, 'final', 0) class error(Exception): def __init__(self, scrypt_code): if isinstance(scrypt_code, int): self._scrypt_code = scrypt_code super(error, self).__init__(ERROR_MESSAGES[scrypt_code]) else: self._scrypt_code = -1 super(error, self).__init__(scrypt_code) def _ensure_bytes(data): if IS_PY2 and isinstance(data, unicode): raise TypeError('can not encrypt/decrypt unicode objects') if not IS_PY2 and isinstance(data, str): return bytes(data, 'utf-8') return data def encrypt(input, password, maxtime=MAXTIME_DEFAULT_ENC, maxmem=MAXMEM_DEFAULT, maxmemfrac=MAXMEMFRAC_DEFAULT): """ Encrypt a string using a password. The resulting data will have len = len(input) + 128. Notes for Python 2: - `input` and `password` must be str instances - The result will be a str instance Notes for Python 3: - `input` and `password` can be both str and bytes. If they are str instances, they will be encoded with utf-8 - The result will be a bytes instance Exceptions raised: - TypeError on invalid input - scrypt.error if encryption failed For more information on the `maxtime`, `maxmem`, and `maxmemfrac` parameters, see the scrypt documentation. """ input = _ensure_bytes(input) password = _ensure_bytes(password) outbuf = create_string_buffer(len(input) + 128) result = _scryptenc_buf(input, len(input), outbuf, password, len(password), maxmem, maxmemfrac, maxtime) if result: raise error(result) return outbuf.raw def decrypt(input, password, maxtime=MAXTIME_DEFAULT, maxmem=MAXMEM_DEFAULT, maxmemfrac=MAXMEMFRAC_DEFAULT, encoding='utf-8'): """ Decrypt a string using a password. Notes for Python 2: - `input` and `password` must be str instances - The result will be a str instance - The encoding parameter is ignored Notes for Python 3: - `input` and `password` can be both str and bytes. If they are str instances, they wil be encoded with utf-8. `input` *should* really be a bytes instance, since that's what `encrypt` returns. - The result will be a str instance encoded with `encoding`. If encoding=None, the result will be a bytes instance. Exceptions raised: - TypeError on invalid input - scrypt.error if decryption failed For more information on the `maxtime`, `maxmem`, and `maxmemfrac` parameters, see the scrypt documentation. """ outbuf = create_string_buffer(len(input)) outbuflen = pointer(c_size_t(0)) input = _ensure_bytes(input) password = _ensure_bytes(password) result = _scryptdec_buf(input, len(input), outbuf, outbuflen, password, len(password), maxmem, maxmemfrac, maxtime) if result: raise error(result) out_bytes = outbuf.raw[:outbuflen.contents.value] if IS_PY2 or encoding is None: return out_bytes return str(out_bytes, encoding) def hash(password, salt, N=1 << 14, r=8, p=1, buflen=64): """ Compute scrypt(password, salt, N, r, p, buflen). The parameters r, p, and buflen must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32. The parameter N must be a power of 2 greater than 1. N, r and p must all be positive. Notes for Python 2: - `password` and `salt` must be str instances - The result will be a str instance Notes for Python 3: - `password` and `salt` can be both str and bytes. If they are str instances, they wil be encoded with utf-8. - The result will be a bytes instance Exceptions raised: - TypeError on invalid input - scrypt.error if scrypt failed """ outbuf = create_string_buffer(buflen) password = _ensure_bytes(password) salt = _ensure_bytes(salt) if r * p >= (1 << 30) or N <= 1 or (N & (N - 1)) != 0 or p < 1 or r < 1: raise error('hash parameters are wrong (r*p should be < 2**30, and N should be a power of two > 1)') result = _crypto_scrypt(password, len(password), salt, len(salt), N, r, p, outbuf, buflen) if result: raise error('could not compute hash') return outbuf.raw __all__ = ['error', 'encrypt', 'decrypt', 'hash'] scrypt-0.8.0/setup.cfg0000644000076500000240000000007312767242550015445 0ustar mhallinstaff00000000000000[egg_info] tag_build = tag_date = 0 tag_svn_revision = 0 scrypt-0.8.0/setup.py0000644000076500000240000000757012767242422015345 0ustar mhallinstaff00000000000000#!/usr/bin/env python from setuptools import setup, Extension import sys import platform import struct includes = [] library_dirs = [] extra_sources = [] CFLAGS = [] if sys.platform.startswith('linux'): define_macros = [('HAVE_CLOCK_GETTIME', '1'), ('HAVE_LIBRT', '1'), ('HAVE_POSIX_MEMALIGN', '1'), ('HAVE_STRUCT_SYSINFO', '1'), ('HAVE_STRUCT_SYSINFO_MEM_UNIT', '1'), ('HAVE_STRUCT_SYSINFO_TOTALRAM', '1'), ('HAVE_SYSINFO', '1'), ('HAVE_SYS_SYSINFO_H', '1'), ('_FILE_OFFSET_BITS', '64')] libraries = ['crypto', 'rt'] CFLAGS.append('-O2') elif sys.platform.startswith('win32'): define_macros = [('inline', '__inline')] libraries = ['libeay32', 'advapi32'] extra_sources = ['scrypt-windows-stubs/gettimeofday.c'] if struct.calcsize('P') == 8: library_dirs = ['c:\OpenSSL-Win64\lib'] includes = ['c:\OpenSSL-Win64\include', 'scrypt-windows-stubs/include'] else: library_dirs = ['c:\OpenSSL-Win32\lib'] includes = ['c:\OpenSSL-Win32\include', 'scrypt-windows-stubs/include'] elif sys.platform.startswith('darwin') and platform.mac_ver()[0] < '10.6': define_macros = [('HAVE_SYSCTL_HW_USERMEM', '1')] libraries = ['crypto'] else: define_macros = [('HAVE_POSIX_MEMALIGN', '1'), ('HAVE_SYSCTL_HW_USERMEM', '1')] libraries = ['crypto'] scrypt_module = Extension( '_scrypt', sources=['src/scrypt.c', 'scrypt-1.2.0/lib/crypto/crypto_scrypt_smix_sse2.c', 'scrypt-1.2.0/lib/crypto/crypto_scrypt_smix.c', 'scrypt-1.2.0/lib/crypto/crypto_scrypt.c', 'scrypt-1.2.0/lib/scryptenc/scryptenc.c', 'scrypt-1.2.0/lib/scryptenc/scryptenc_cpuperf.c', 'scrypt-1.2.0/lib/util/memlimit.c', 'scrypt-1.2.0/libcperciva/alg/sha256.c', 'scrypt-1.2.0/libcperciva/crypto/crypto_aes_aesni.c', 'scrypt-1.2.0/libcperciva/crypto/crypto_aes.c', 'scrypt-1.2.0/libcperciva/crypto/crypto_aesctr.c', 'scrypt-1.2.0/libcperciva/crypto/crypto_entropy.c', 'scrypt-1.2.0/libcperciva/util/entropy.c', 'scrypt-1.2.0/libcperciva/util/insecure_memzero.c', 'scrypt-1.2.0/libcperciva/util/warnp.c'] + extra_sources, include_dirs=['scrypt-1.2.0', 'scrypt-1.2.0/lib', 'scrypt-1.2.0/lib/scryptenc', 'scrypt-1.2.0/lib/crypto', 'scrypt-1.2.0/lib/util', 'scrypt-1.2.0/libcperciva/cpusupport', 'scrypt-1.2.0/libcperciva/alg', 'scrypt-1.2.0/libcperciva/util', 'scrypt-1.2.0/libcperciva/crypto'] + includes, define_macros=[('HAVE_CONFIG_H', None)] + define_macros, extra_compile_args=CFLAGS, library_dirs=library_dirs, libraries=libraries) setup(name='scrypt', version='0.8.0', description='Bindings for the scrypt key derivation function library', author='Magnus Hallin', author_email='mhallin@gmail.com', url='http://bitbucket.org/mhallin/py-scrypt', py_modules=['scrypt'], ext_modules=[scrypt_module], classifiers=['Development Status :: 4 - Beta', 'Intended Audience :: Developers', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', 'Topic :: Security :: Cryptography', 'Topic :: Software Development :: Libraries'], license='2-clause BSD', long_description=open('README.rst').read(), test_suite='tests.all_tests') scrypt-0.8.0/src/0000755000076500000240000000000012767242550014413 5ustar mhallinstaff00000000000000scrypt-0.8.0/src/scrypt.c0000644000076500000240000000645012546213420016075 0ustar mhallinstaff00000000000000/*- * Copyright 2010 Magnus Hallin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include #include "scryptenc.h" #include "crypto_scrypt.h" #if !defined(DL_EXPORT) #if defined(HAVE_DECLSPEC_DLL) #define DL_EXPORT(type) __declspec(dllexport) type #else #define DL_EXPORT(type) type #endif #endif /* Exported trampolines */ DL_EXPORT(int) exp_scryptenc_buf(const uint8_t *inbuf, size_t inbuflen, uint8_t *outbuf, const uint8_t *passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { return scryptenc_buf(inbuf, inbuflen, outbuf, passwd, passwdlen, maxmem, maxmemfrac, maxtime); } DL_EXPORT(int) exp_scryptdec_buf(const uint8_t *inbuf, size_t inbuflen, uint8_t *outbuf, size_t *outbuflen, const uint8_t *passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { return scryptdec_buf(inbuf, inbuflen, outbuf, outbuflen, passwd, passwdlen, maxmem, maxmemfrac, maxtime); } DL_EXPORT(int) exp_crypto_scrypt(const uint8_t *passwd, size_t passwdlen, const uint8_t *salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p, uint8_t *buf, size_t buflen) { return crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen); } /* We need a stub init_scrypt function so the module will link as a proper module. */ static PyMethodDef scrypt_methods[] = { {NULL, NULL, 0, NULL}, }; #if PY_MAJOR_VERSION == 2 PyMODINIT_FUNC init_scrypt(void) { Py_InitModule("_scrypt", scrypt_methods); } #endif #if PY_MAJOR_VERSION == 3 static struct PyModuleDef scrypt_module = { PyModuleDef_HEAD_INIT, "_scrypt", NULL, -1, scrypt_methods }; PyMODINIT_FUNC PyInit__scrypt(void) { return PyModule_Create(&scrypt_module); } #endif scrypt-0.8.0/tests/0000755000076500000240000000000012767242550014766 5ustar mhallinstaff00000000000000scrypt-0.8.0/tests/__init__.py0000644000076500000240000000164312546212401017066 0ustar mhallinstaff00000000000000from sys import version_info, exit from .test_scrypt import TestScrypt, TestScryptHash from .test_scrypt_c_module import TestScryptCModule from .test_scrypt_py2x import TestScryptForPython2 from .test_scrypt_py3x import TestScryptForPy3 if ((version_info > (3, 2, 0, 'final', 0)) or (version_info > (2, 7, 0, 'final', 0) and version_info < (3, 0, 0, 'final', 0))): import unittest as testm else: try: import unittest2 as testm except ImportError: print("Please install unittest2 to run the test suite") exit(-1) def all_tests(): suite = testm.TestSuite() loader = testm.TestLoader() test_classes = [ TestScrypt, TestScryptCModule, TestScryptHash, TestScryptForPython2, TestScryptForPy3, ] for cls in test_classes: tests = loader.loadTestsFromTestCase(cls) suite.addTests(tests) return suite scrypt-0.8.0/tests/ciphertexts.csv0000644000076500000240000000310112546200322020022 0ustar mhallinstaff00000000000000input,password,maxtime,maxmem,maxmemfrac,ciphertext message,password,0.01,0,0.0625,736372797074000a00000008000000019f6d3fe5e9423a12d330e35089befdfbb476c7d4faea91492a2561f942c1599701aba424220218b9f81812df06d7cf2a281fd0fdbc7c9d978c335bf5209b1062ee2e49993c4d3a37d347ad6bf0eaecc2fe579a6f320b0acf475882c222c0ba34a7ac5379bedc82358bb3f736ea31d4b824e8bc95c75579 message,password,5.0000,0.0000,0.1250,736372797074000a00000008000000cb974d55992fea307caa3593205c8851cd56b3ddfd241ee7b1c075cfd2e2f871dddcee71b6bc2b6b075caa1699ea58ce32e9fcd802b18069828201692380574e23e84c2d39d6a951c9c2401dea1a0fa44195b01fca9332f7aac223c84251c69a28037788e09cf297a003a62e2e7c5b6f039e3c1d21fa5da6 message,password,0.5000,0.0000,0.0625,736372797074000a00000008000000141429bb22aef840e1dde29564dada8f2a77fc2855fe8c9e27e5bf5df4a0eec330344e8471bf83e2466a28acc9d1813a3e50e64697fb8e9c7c17954950f16a5b78fe114d8b147c5936802fe52b17f83e6da9de884257f2a938aa37c2e92b1c33cd9afd0f5e91baba29be4b1c0709bd2a31a4c52394f9b0d4 message,password,0.5000,0.0000,0.1250,736372797074000a0000000800000014e9baa49b57b2e5b561df54121d870532714f063f295c15ca48e32b677e8e11126ab8da24683951749a19eede36ea3768cb01e8eda6c0f570db7051e07e99d2d687ce28f96aa2e6afa8a0a8c5d902c847e041e14435a22d873c4e676f7a7f5ab9107171b583d02724c056707640931a3c160b9e0ef87bae message,password,0.5000,10485760.0000,0.1250,736372797074000a0000000800000014e53c55cd89b6e2de639c1621d92e79212e5f4fc793387435486427eb8adeb192382b5b6397f98ac66fa528a13cba01bd611082369fe1e2244a01ba8329ff6fcaa2db5e87fb75683ae6fc636d873c2e004a0209b947c7b8e805174d65ec0ac2cb597baadae6cf092c33a5096590860b51570faa89e39bf0scrypt-0.8.0/tests/hashvectors.csv0000644000076500000240000000122312465734374020037 0ustar mhallinstaff00000000000000password,salt,n,r,p,hexhash ,,16,1,1,77d6576238657b203b19ca42c18a0497f16b4844e3074ae8dfdffa3fede21442fcd0069ded0948f8326a753a0fc81f17e8d3e0fb2e0d3628cf35e20c38d18906 password,NaCl,1024,8,16,fdbabe1c9d3472007856e7190d01e9fe7c6ad7cbc8237830e77376634b3731622eaf30d92e22a3886ff109279d9830dac727afb94a83ee6d8360cbdfa2cc0640 pleaseletmein,SodiumChloride,16384,8,1,7023bdcb3afd7348461c06cd81fd38ebfda8fbba904f8e3ea9b543f6545da1f2d5432955613f0fcf62d49705242a9af9e61e85dc0d651e40dfcf017b45575887 pleaseletmein,SodiumChloride,32768,16,4,cbc397a9b5f5a53048c5b9f039ee1246d9532c8089fb346a4ab47cd0701febf18652b1ee042e070d1b6c631c43fd05ececd5b165ee1c2ffc1a2e98406fc2cd52scrypt-0.8.0/tests/test_scrypt.py0000644000076500000240000002765512546260221017730 0ustar mhallinstaff00000000000000# -*- coding: utf-8 -*- from os import urandom from os.path import dirname, abspath, sep from sys import version_info, exit from csv import reader from binascii import a2b_hex, b2a_hex import scrypt if ((version_info > (3, 2, 0, 'final', 0)) or (version_info > (2, 7, 0, 'final', 0) and version_info < (3, 0, 0, 'final', 0))): import unittest as testm else: try: import unittest2 as testm except ImportError: print("Please install unittest2 to run the test suite") exit(-1) class TestScrypt(testm.TestCase): def setUp(self): self.input = "message" self.password = "password" self.longinput = str(urandom(100000)) self.five_minutes = 300.0 self.five_seconds = 5.0 self.one_byte = 1 # in Bytes self.one_megabyte = 1024 * 1024 # in Bytes self.ten_megabytes = 10 * self.one_megabyte base_dir = dirname(abspath(__file__)) + sep cvf = open(base_dir + "ciphertexts.csv", "r") ciphertxt_reader = reader(cvf, dialect="excel") self.ciphertexts = [] for row in ciphertxt_reader: self.ciphertexts.append(row) cvf.close() self.ciphertext = a2b_hex(bytes(self.ciphertexts[1][5].encode('ascii'))) def test_encrypt_decrypt(self): """Test encrypt for simple encryption and decryption""" s = scrypt.encrypt(self.input, self.password, 0.1) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt(self): """Test encrypt takes input and password strings as positional arguments and produces ciphertext""" s = scrypt.encrypt(self.input, self.password) self.assertEqual(len(s), 128 + len(self.input)) def test_encrypt_input_and_password_as_keywords(self): """Test encrypt for input and password accepted as keywords""" s = scrypt.encrypt(password=self.password, input=self.input) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_missing_input_keyword_argument(self): """Test encrypt raises TypeError if keyword argument missing input""" self.assertRaises(TypeError, lambda: scrypt.encrypt(password=self.password)) def test_encrypt_missing_password_positional_argument(self): """Test encrypt raises TypeError if second positional argument missing (password)""" self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input)) def test_encrypt_missing_both_required_positional_arguments(self): """Test encrypt raises TypeError if both positional arguments missing (input and password)""" self.assertRaises(TypeError, lambda: scrypt.encrypt()) def test_encrypt_maxtime_positional(self): """Test encrypt maxtime accepts maxtime at position 3""" s = scrypt.encrypt(self.input, self.password, 0.01) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_maxtime_key(self): """Test encrypt maxtime accepts maxtime as keyword argument""" s = scrypt.encrypt(self.input, self.password, maxtime=0.01) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_maxmem_positional(self): """Test encrypt maxmem accepts 4th positional argument and exactly (1 megabyte) of storage to use for V array""" s = scrypt.encrypt(self.input, self.password, 0.01, self.one_megabyte) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_maxmem_undersized(self): """Test encrypt maxmem accepts (< 1 megabyte) of storage to use for V array""" s = scrypt.encrypt(self.input, self.password, 0.01, self.one_byte) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_maxmem_in_normal_range(self): """Test encrypt maxmem accepts (> 1 megabyte) of storage to use for V array""" s = scrypt.encrypt(self.input, self.password, 0.01, self.ten_megabytes) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_maxmem_keyword_argument(self): """Test encrypt maxmem accepts exactly (1 megabyte) of storage to use for V array""" s = scrypt.encrypt(self.input, self.password, maxmem=self.one_megabyte, maxtime=0.01) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_maxmemfrac_positional(self): """Test encrypt maxmemfrac accepts 5th positional argument of 1/16 total memory for V array""" s = scrypt.encrypt(self.input, self.password, 0.01, 0, 0.0625) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_maxmemfrac_keyword_argument(self): """Test encrypt maxmemfrac accepts keyword argument of 1/16 total memory for V array""" s = scrypt.encrypt(self.input, self.password, maxmemfrac=0.0625, maxtime=0.01) m = scrypt.decrypt(s, self.password) self.assertEqual(m, self.input) def test_encrypt_long_input(self): """Test encrypt accepts long input for encryption""" s = scrypt.encrypt(self.longinput, self.password, 0.1) self.assertEqual(len(s), 128 + len(self.longinput)) def test_encrypt_raises_error_on_invalid_keyword(self): """Test encrypt raises TypeError if invalid keyword used in argument""" self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input, self.password, nonsense="Raise error")) def test_decrypt_from_csv_ciphertexts(self): """Test decrypt function with precalculated combinations""" for row in self.ciphertexts[1:]: h = scrypt.decrypt(a2b_hex(bytes(row[5].encode('ascii'))), row[1]) self.assertEqual(bytes(h.encode("ascii")), row[0].encode("ascii")) def test_decrypt_maxtime_positional(self): """Test decrypt function accepts third positional argument""" m = scrypt.decrypt(self.ciphertext, self.password, self.five_seconds) self.assertEqual(m, self.input) def test_decrypt_maxtime_keyword_argument(self): """Test decrypt function accepts maxtime keyword argument""" m = scrypt.decrypt(maxtime=1.0, input=self.ciphertext, password=self.password) self.assertEqual(m, self.input) def test_decrypt_maxmem_positional(self): """Test decrypt function accepts fourth positional argument""" m = scrypt.decrypt(self.ciphertext, self.password, self.five_minutes, self.ten_megabytes) self.assertEqual(m, self.input) def test_decrypt_maxmem_keyword_argument(self): """Test decrypt function accepts maxmem keyword argument""" m = scrypt.decrypt(maxmem=self.ten_megabytes, input=self.ciphertext, password=self.password) self.assertEqual(m, self.input) def test_decrypt_maxmemfrac_positional(self): """Test decrypt function accepts maxmem keyword argument""" m = scrypt.decrypt(self.ciphertext, self.password, self.five_minutes, self.one_megabyte, 0.0625) self.assertEqual(m, self.input) def test_decrypt_maxmemfrac_keyword_argument(self): """Test decrypt function accepts maxmem keyword argument""" m = scrypt.decrypt(maxmemfrac=0.625, input=self.ciphertext, password=self.password) self.assertEqual(m, self.input) def test_decrypt_raises_error_on_too_little_time(self): """Test decrypt function raises scrypt.error raised if insufficient time allowed for ciphertext decryption""" s = scrypt.encrypt(self.input, self.password, 0.1) self.assertRaises(scrypt.error, lambda: scrypt.decrypt(s, self.password, .01)) class TestScryptHash(testm.TestCase): def setUp(self): self.input = "message" self.password = "password" self.salt = "NaCl" self.hashes = [] base_dir = dirname(abspath(__file__)) + sep hvf = open(base_dir + "hashvectors.csv", "r") hash_reader = reader(hvf, dialect="excel") for row in hash_reader: self.hashes.append(row) hvf.close() def test_hash_vectors_from_csv(self): """Test hash function with precalculated combinations""" for row in self.hashes[1:]: h = scrypt.hash(row[0], row[1], int(row[2]), int(row[3]), int(row[4])) hhex = b2a_hex(h) self.assertEqual(hhex, bytes(row[5].encode("utf-8"))) def test_hash_buflen_keyword(self): """Test hash takes keyword valid buflen""" h64 = scrypt.hash(self.input, self.salt, buflen=64) h128 = scrypt.hash(self.input, self.salt, buflen=128) self.assertEqual(len(h64), 64) self.assertEqual(len(h128), 128) def test_hash_n_positional(self): """Test hash accepts valid N in position 3""" h = scrypt.hash(self.input, self.salt, 256) self.assertEqual(len(h), 64) def test_hash_n_keyword(self): """Test hash takes keyword valid N""" h = scrypt.hash(N=256, password=self.input, salt=self.salt) self.assertEqual(len(h), 64) def test_hash_r_positional(self): """Test hash accepts valid r in position 4""" h = scrypt.hash(self.input, self.salt, 256, 16) self.assertEqual(len(h), 64) def test_hash_r_keyword(self): """Test hash takes keyword valid r""" h = scrypt.hash(r=16, password=self.input, salt=self.salt) self.assertEqual(len(h), 64) def test_hash_p_positional(self): """Test hash accepts valid p in position 5""" h = scrypt.hash(self.input, self.salt, 256, 8, 2) self.assertEqual(len(h), 64) def test_hash_p_keyword(self): """Test hash takes keyword valid p""" h = scrypt.hash(p=4, password=self.input, salt=self.salt) self.assertEqual(len(h), 64) def test_hash_raises_error_on_p_equals_zero(self): """Test hash raises scrypt error on illegal parameter value (p = 0)""" self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, p=0)) def test_hash_raises_error_on_negative_p(self): """Test hash raises scrypt error on illegal parameter value (p < 0)""" self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, p=-1)) def test_hash_raises_error_on_r_equals_zero(self): """Test hash raises scrypt error on illegal parameter value (r = 0)""" self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, r=0)) def test_hash_raises_error_on_negative_r(self): """Test hash raises scrypt error on illegal parameter value (r < 1)""" self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, r=-1)) def test_hash_raises_error_r_p_over_limit(self): """Test hash raises scrypt error when parameters r multiplied by p over limit 2**30""" self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, r=2, p=2 ** 29)) def test_hash_raises_error_n_not_power_of_two(self): """Test hash raises scrypt error when parameter N is not a power of two {2, 4, 8, 16, etc}""" self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, N=3)) def test_hash_raises_error_n_under_limit(self): """Test hash raises scrypt error when parameter N under limit of 1""" self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, N=1)) self.assertRaises(scrypt.error, lambda: scrypt.hash(self.input, self.salt, N=-1)) if __name__ == "__main__": testm.main() scrypt-0.8.0/tests/test_scrypt_py2x.py0000644000076500000240000000350212546174245020705 0ustar mhallinstaff00000000000000# -*- coding: utf-8 -*- from sys import version_info, exit import scrypt if ((version_info > (3, 2, 0, 'final', 0)) or (version_info > (2, 7, 0, 'final', 0) and version_info < (3, 0, 0, 'final', 0))): import unittest as testm else: try: import unittest2 as testm except ImportError: print("Please install unittest2 to run the test suite") exit(-1) @testm.skipIf(version_info > (3, 0, 0, 'final', 0), "Tests for Python 2 only") class TestScryptForPython2(testm.TestCase): def setUp(self): self.input = "message" self.password = "password" self.unicode_text = '\xe1\x93\x84\xe1\x93\x87\xe1\x95\x97\xe1\x92\xbb\xe1\x92\xa5\xe1\x90\x85\xe1\x91\xa6'.decode('utf-8') def test_py2_encrypt_fails_on_unicode_input(self): """Test Py2 encrypt raises TypeError when Unicode input passed""" self.assertRaises(TypeError, lambda: scrypt.encrypt(self.unicode_text, self.password)) def test_py2_encrypt_fails_on_unicode_password(self): """Test Py2 encrypt raises TypeError when Unicode password passed""" self.assertRaises(TypeError, lambda: scrypt.encrypt(self.input, self.unicode_text)) def test_py2_encrypt_returns_string(self): """Test Py2 encrypt returns str""" e = scrypt.encrypt(self.input, self.password, 0.1) self.assertTrue(isinstance(e, str)) def test_py2_decrypt_returns_string(self): """Test Py2 decrypt returns str""" s = scrypt.encrypt(self.input, self.password, 0.1) m = scrypt.decrypt(s, self.password) self.assertTrue(isinstance(m, str)) def test_py2_hash_returns_string(self): """Test Py2 hash return str""" h = scrypt.hash(self.input, self.password) self.assertTrue(isinstance(h, str)) if __name__ == "__main__": testm.main() scrypt-0.8.0/tests/test_scrypt_py3x.py0000644000076500000240000000374112546174256020715 0ustar mhallinstaff00000000000000# -*- coding: utf-8 -*- from sys import version_info, exit import scrypt if ((version_info > (3, 2, 0, 'final', 0)) or (version_info > (2, 7, 0, 'final', 0) and version_info < (3, 0, 0, 'final', 0))): import unittest as testm else: try: import unittest2 as testm except ImportError: print("Please install unittest2 to run the test suite") exit(-1) @testm.skipIf(version_info < (3, 0, 0, 'final', 0), "Tests for Python 3 only") class TestScryptForPy3(testm.TestCase): def setUp(self): self.input = "message" self.password = "password" self.byte_text = b'\xe1\x93\x84\xe1\x93\x87\xe1\x95\x97\xe1\x92\xbb\xe1\x92\xa5\xe1\x90\x85\xe1\x91\xa6' self.unicode_text = self.byte_text.decode('utf-8', "strict") def test_py3_encrypt_allows_bytes_input(self): """Test Py3 encrypt allows unicode input""" s = scrypt.encrypt(self.byte_text, self.password, 0.1) m = scrypt.decrypt(s, self.password) self.assertEqual(bytes(m.encode("utf-8")), self.byte_text) def test_py3_encrypt_allows_bytes_password(self): """Test Py3 encrypt allows unicode password""" s = scrypt.encrypt(self.input, self.byte_text, 0.1) m = scrypt.decrypt(s, self.byte_text) self.assertEqual(m, self.input) def test_py3_encrypt_returns_bytes(self): """Test Py3 encrypt return bytes""" s = scrypt.encrypt(self.input, self.password, 0.1) self.assertTrue(isinstance(s, bytes)) def test_py3_decrypt_returns_unicode_string(self): """Test Py3 decrypt returns Unicode UTF-8 string""" s = scrypt.encrypt(self.input, self.password, 0.1) m = scrypt.decrypt(s, self.password) self.assertTrue(isinstance(m, str)) def test_py3_hash_returns_bytes(self): """Test Py3 hash return bytes""" h = scrypt.hash(self.input, self.password) self.assertTrue(isinstance(h, bytes)) if __name__ == "__main__": testm.main()