python-scrypt-0.6.1/0000755000175000017500000000000012134477552013317 5ustar micahmicahpython-scrypt-0.6.1/PKG-INFO0000644000175000017500000001336312134477552014422 0ustar micahmicahMetadata-Version: 1.0 Name: scrypt Version: 0.6.1 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 randstr(length): return ''.join(chr(random.randint(0,255)) for i in range(length)) def hash_password(password, maxtime=0.5, datalength=64): return scrypt.encrypt(randstr(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. 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 Platform: UNKNOWN Classifier: Development Status :: 4 - Beta Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: Python :: 2.6 Classifier: Programming Language :: Python :: 2.7 Classifier: Programming Language :: Python :: 3 Classifier: Topic :: Security :: Cryptography Classifier: Topic :: Software Development :: Libraries python-scrypt-0.6.1/src/0000755000175000017500000000000012134477552014106 5ustar micahmicahpython-scrypt-0.6.1/src/scrypt.c0000644000175000017500000000603412040043160015555 0ustar micahmicah/*- * 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. Do not import _scrypt from python; it will not work since _scrypt is not a *real* module */ PyMODINIT_FUNC init_scrypt(void) { } PyMODINIT_FUNC PyInit__scrypt(void) { } python-scrypt-0.6.1/scrypt.py0000644000175000017500000001714412040212520015176 0ustar micahmicahimport 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'] python-scrypt-0.6.1/scrypt-1.1.6/0000755000175000017500000000000012134477552015304 5ustar micahmicahpython-scrypt-0.6.1/scrypt-1.1.6/scrypt_platform.h0000644000175000017500000000040711767303130020675 0ustar micahmicah#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_ */ python-scrypt-0.6.1/scrypt-1.1.6/config.h0000644000175000017500000000555511767303130016723 0ustar micahmicah/* 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 1 /* 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.1.6" /* 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.1.6" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 /* Version number of package */ #define VERSION "1.1.6" /* 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 */ python-scrypt-0.6.1/scrypt-1.1.6/lib/0000755000175000017500000000000012134477552016052 5ustar micahmicahpython-scrypt-0.6.1/scrypt-1.1.6/lib/util/0000755000175000017500000000000012134477552017027 5ustar micahmicahpython-scrypt-0.6.1/scrypt-1.1.6/lib/util/memlimit.h0000644000175000017500000000344311767303130021010 0ustar micahmicah/*- * 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_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/util/warn.h0000644000175000017500000000033711767303130020141 0ustar micahmicah#ifndef _WARN_H_ #define _WARN_H_ #ifdef HAVE_ERR_H #include #else #define NEED_WARN_PROGNAME const char * warn_progname; void warn(const char *, ...); void warnx(const char *, ...); #endif #endif /* !_WARN_H_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/util/memlimit.c0000644000175000017500000001766611767303130021017 0ustar micahmicah/*- * 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 #ifdef _WIN32 #define _WIN32_WINNT 0x0502 #include #include #endif #ifdef HAVE_SYS_PARAM_H #include #endif #ifdef HAVE_SYSCTL_HW_USERMEM #include #endif #ifdef HAVE_SYS_SYSINFO_H #include #endif #include #include #include #include #ifdef DEBUG #include #endif #include "memlimit.h" #ifdef HAVE_SYSCTL_HW_USERMEM static int memlimit_sysctl_hw_usermem(size_t * memlimit) { int mib[2]; uint8_t usermembuf[8]; size_t usermemlen = 8; uint64_t usermem; /* Ask the kernel how much RAM we have. */ mib[0] = CTL_HW; mib[1] = HW_USERMEM; if (sysctl(mib, 2, usermembuf, &usermemlen, NULL, 0)) return (1); /* * Parse as either a uint64_t or a uint32_t based on the length of * output the kernel reports having copied out. It appears that all * systems providing a sysctl interface for reading integers copy * them out as system-endian values, so we don't need to worry about * parsing them. */ if (usermemlen == sizeof(uint64_t)) usermem = *(uint64_t *)usermembuf; else if (usermemlen == sizeof(uint32_t)) usermem = *(uint32_t *)usermembuf; else return (1); /* Return the sysctl value, but clamp to SIZE_MAX if necessary. */ #if UINT64_MAX > SIZE_MAX if (usermem > SIZE_MAX) *memlimit = SIZE_MAX; else *memlimit = usermem; #else *memlimit = usermem; #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 sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit; size_t sysconf_memlimit; size_t memlimit_min; size_t memavail; size_t windows_memlimit; /* Get memory limits. */ #ifdef HAVE_SYSCTL_HW_USERMEM if (memlimit_sysctl_hw_usermem(&sysctl_memlimit)) return (1); #else sysctl_memlimit = (size_t)(-1); #endif #ifdef HAVE_SYSINFO if (memlimit_sysinfo(&sysinfo_memlimit)) return (1); #else sysinfo_memlimit = (size_t)(-1); #endif #ifndef _WIN32 if (memlimit_rlimit(&rlimit_memlimit)) return (1); #else rlimit_memlimit=(size_t)(-1); #endif #ifdef _SC_PHYS_PAGES if (memlimit_sysconf(&sysconf_memlimit)) return (1); #else sysconf_memlimit = (size_t)(-1); #endif #ifdef _WIN32 if (memlimit_windows(&windows_memlimit)) return (1); #else windows_memlimit=(size_t)(-1); #endif #ifdef DEBUG fprintf(stderr, "Memory limits are %u %u %u %u %u\n", sysctl_memlimit, sysinfo_memlimit, rlimit_memlimit, sysconf_memlimit, windows_memlimit); #endif /* Find the smallest of them. */ memlimit_min = (size_t)(-1); if (memlimit_min > sysctl_memlimit) memlimit_min = sysctl_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 %u memory to be used\n", memavail); #endif /* Return limit via the provided pointer. */ *memlimit = memavail; return (0); } python-scrypt-0.6.1/scrypt-1.1.6/lib/util/readpass.h0000644000175000017500000000432111767303130020771 0ustar micahmicah/*- * 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 _READPASS_H_ #define _READPASS_H_ /** * tarsnap_getpass(passwd, prompt, confirmprompt, devtty) * If ${devtty} is non-zero, read a password from /dev/tty if possible; if * not, read from stdin. If reading from a tty (either /dev/tty or stdin), * disable echo and prompt the user by printing ${prompt} to stderr. If * ${confirmprompt} is non-NULL, read a second password (prompting if a * terminal is being used) and repeat until the user enters the same password * twice. Return the password as a malloced NUL-terminated string via * ${passwd}. The obscure name is to avoid namespace collisions due to the * getpass / readpass / readpassphrase / etc. functions in various libraries. */ int tarsnap_readpass(char **, const char *, const char *, int); #endif /* !_READPASS_H_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/util/sysendian.h0000644000175000017500000000732511767303130021173 0ustar micahmicah/*- * Copyright 2007-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 _SYSENDIAN_H_ #define _SYSENDIAN_H_ #include "scrypt_platform.h" /* If we don't have be64enc, the we have isn't usable. */ #if !HAVE_DECL_BE64ENC #undef HAVE_SYS_ENDIAN_H #endif #ifdef HAVE_SYS_ENDIAN_H #include #else #include 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 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 /* !HAVE_SYS_ENDIAN_H */ #endif /* !_SYSENDIAN_H_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/util/warn.c0000644000175000017500000000430311767303130020131 0ustar micahmicah/*- * 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" #ifdef HAVE_ERR_H /* * Everything is provided through err.h and the associated library, so we * don't need to do anything here. */ #else #include #include #include #include #include "warn.h" const char * warn_progname = "(null)"; void warn(const char * fmt, ...) { va_list ap; va_start(ap, fmt); fprintf(stderr, "%s", warn_progname); 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", warn_progname); if (fmt != NULL) { fprintf(stderr, ": "); vfprintf(stderr, fmt, ap); } fprintf(stderr, "\n"); va_end(ap); } #endif python-scrypt-0.6.1/scrypt-1.1.6/lib/scryptenc/0000755000175000017500000000000012134477552020064 5ustar micahmicahpython-scrypt-0.6.1/scrypt-1.1.6/lib/scryptenc/scryptenc.h0000644000175000017500000001116111767303130022236 0ustar micahmicah/*- * 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 /** * 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_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/scryptenc/scryptenc.c0000644000175000017500000003733111767303130022240 0ustar micahmicah/*- * 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 #include "crypto_aesctr.h" #include "crypto_scrypt.h" #include "memlimit.h" #include "scryptenc_cpuperf.h" #include "sha256.h" #include "sysendian.h" #include "scryptenc.h" #ifdef _WIN32 #include #include #endif #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 getsalt(uint8_t[32]); 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 <= %u, 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 = %u 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 getsalt(uint8_t salt[32]) { int fd; ssize_t lenread; uint8_t * buf = salt; size_t buflen = 32; #ifndef _WIN32 /* Open /dev/urandom. */ if ((fd = open("/dev/urandom", O_RDONLY)) == -1) goto err0; /* Read bytes until we have filled the buffer. */ while (buflen > 0) { if ((lenread = read(fd, buf, buflen)) == -1) goto err1; /* The random device should never EOF. */ if (lenread == 0) goto err1; /* We're partly done. */ buf += lenread; buflen -= lenread; } /* Close the device. */ while (close(fd) == -1) { if (errno != EINTR) goto err0; } /* Success! */ return (0); err1: close(fd); err0: /* Failure! */ return (4); #else 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(); printf("%x", error); return (14); } } if(CryptGenRandom(context, 32, buf)) { buf += 32; return (0); } else{return(15);} #endif } 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; scrypt_SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; HMAC_scrypt_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 ((rc = getsalt(salt)) != 0) return (rc); /* 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. */ scrypt_SHA256_Init(&ctx); scrypt_SHA256_Update(&ctx, header, 48); scrypt_SHA256_Final(hbuf, &ctx); memcpy(&header[48], hbuf, 16); /* Add header signature (used for verifying password). */ HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); HMAC_scrypt_SHA256_Update(&hctx, header, 64); HMAC_scrypt_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; scrypt_SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; HMAC_scrypt_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. */ scrypt_SHA256_Init(&ctx); scrypt_SHA256_Update(&ctx, header, 48); scrypt_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_scrypt_SHA256_Init(&hctx, key_hmac, 32); HMAC_scrypt_SHA256_Update(&hctx, header, 64); HMAC_scrypt_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_scrypt_SHA256_CTX hctx; 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 (AES_set_encrypt_key(key_enc, 256, &key_enc_exp)) 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); /* Add signature. */ HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); HMAC_scrypt_SHA256_Update(&hctx, outbuf, 96 + inbuflen); HMAC_scrypt_SHA256_Final(hbuf, &hctx); memcpy(&outbuf[96 + inbuflen], hbuf, 32); /* Zero sensitive data. */ memset(dk, 0, 64); memset(&key_enc_exp, 0, sizeof(AES_KEY)); /* Success! */ return (0); } /** * scryptdec_buf(inbuf, inbuflen, outbuf, outlen, passwd, passwdlen, * maxmem, maxmemfrac, maxtime): * Decrypt inbuflen bytes fro 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_scrypt_SHA256_CTX hctx; 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 (AES_set_encrypt_key(key_enc, 256, &key_enc_exp)) 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); *outlen = inbuflen - 128; /* Verify signature. */ HMAC_scrypt_SHA256_Init(&hctx, key_hmac, 32); HMAC_scrypt_SHA256_Update(&hctx, inbuf, inbuflen - 32); HMAC_scrypt_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, &inbuf[inbuflen - 32], 32)) return (7); /* Zero sensitive data. */ memset(dk, 0, 64); memset(&key_enc_exp, 0, sizeof(AES_KEY)); /* 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_scrypt_SHA256_CTX hctx; 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_scrypt_SHA256_Init(&hctx, key_hmac, 32); HMAC_scrypt_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 (AES_set_encrypt_key(key_enc, 256, &key_enc_exp)) 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_scrypt_SHA256_Update(&hctx, buf, readlen); if (fwrite(buf, 1, readlen, outfile) < readlen) return (12); } while (1); crypto_aesctr_free(AES); /* Did we exit the loop due to a read error? */ if (ferror(infile)) return (13); /* Compute the final HMAC and output it. */ HMAC_scrypt_SHA256_Final(hbuf, &hctx); if (fwrite(hbuf, 32, 1, outfile) != 1) return (12); /* Zero sensitive data. */ memset(dk, 0, 64); memset(&key_enc_exp, 0, sizeof(AES_KEY)); /* 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_scrypt_SHA256_CTX hctx; AES_KEY key_enc_exp; struct crypto_aesctr * AES; int rc; /* * Read the first 7 bytes of the file; all future version 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 srypt 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_scrypt_SHA256_Init(&hctx, key_hmac, 32); HMAC_scrypt_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 (AES_set_encrypt_key(key_enc, 256, &key_enc_exp)) 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_scrypt_SHA256_Update(&hctx, buf, buflen - 32); crypto_aesctr_stream(AES, buf, buf, buflen - 32); if (fwrite(buf, 1, buflen - 32, outfile) < buflen - 32) 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); /* 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_scrypt_SHA256_Final(hbuf, &hctx); if (memcmp(hbuf, buf, 32)) return (7); /* Zero sensitive data. */ memset(dk, 0, 64); memset(&key_enc_exp, 0, sizeof(AES_KEY)); return (0); } python-scrypt-0.6.1/scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.h0000644000175000017500000000330611767303130023764 0ustar micahmicah/*- * 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_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.c0000644000175000017500000001061511767303130023760 0ustar micahmicah/*- * 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 _WIN32 struct timespec { time_t tv_sec; long tv_nsec; }; #endif #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); /* Could how many scryps 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, "%u 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); } python-scrypt-0.6.1/scrypt-1.1.6/lib/crypto/0000755000175000017500000000000012134477552017372 5ustar micahmicahpython-scrypt-0.6.1/scrypt-1.1.6/lib/crypto/crypto_scrypt-nosse.c0000644000175000017500000002155211767303130023603 0ustar micahmicah/*- * 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 "sha256.h" #include "sysendian.h" #include "crypto_scrypt.h" static void blkcpy(void *, void *, size_t); static void blkxor(void *, void *, size_t); static void salsa20_8(uint32_t[16]); static void blockmix_salsa8(uint32_t *, uint32_t *, uint32_t *, size_t); static uint64_t integerify(void *, size_t); static void smix(uint8_t *, size_t, uint64_t, uint32_t *, uint32_t *); static void blkcpy(void * dest, void * src, size_t len) { size_t * D = dest; 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, void * src, size_t len) { size_t * D = dest; 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(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(void * B, size_t r) { uint32_t * X = (void *)((uintptr_t)(B) + (2 * r - 1) * 64); return (((uint64_t)(X[1]) << 32) + X[0]); } /** * 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. */ static void smix(uint8_t * B, size_t r, uint64_t N, uint32_t * V, uint32_t * XY) { uint32_t * X = XY; uint32_t * Y = &XY[32 * r]; uint32_t * Z = &XY[64 * r]; 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]); } /** * 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) { void * B0, * V0, * XY0; uint8_t * B; uint32_t * V; uint32_t * XY; 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 == 0)) { errno = EINVAL; goto err0; } if ((r > SIZE_MAX / 128 / p) || #if SIZE_MAX / 256 <= UINT32_MAX (r > SIZE_MAX / 256) || #endif (N > SIZE_MAX / 128 / r)) { errno = ENOMEM; goto err0; } /* Allocate memory. */ #ifdef _WIN32 #undef HAVE_POSIX_MEMALIGN #endif #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); #ifndef MAP_ANON 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)); #ifndef MAP_ANON if ((V0 = malloc(128 * r * N + 63)) == NULL) goto err2; V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63)); #endif #endif #ifdef MAP_ANON 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_scrypt_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_scrypt_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen); /* Free memory. */ #ifdef MAP_ANON 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); } python-scrypt-0.6.1/scrypt-1.1.6/lib/crypto/sha256.h0000644000175000017500000000503111767303130020541 0ustar micahmicah/*- * Copyright 2005,2007,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. * * $FreeBSD: src/lib/libmd/sha256.h,v 1.2 2006/01/17 15:35:56 phk Exp $ */ #ifndef _scrypt_SHA256_H_ #define _scrypt_SHA256_H_ #include #include typedef struct scrypt_SHA256Context { uint32_t state[8]; uint32_t count[2]; unsigned char buf[64]; } scrypt_SHA256_CTX; typedef struct HMAC_scrypt_SHA256Context { scrypt_SHA256_CTX ictx; scrypt_SHA256_CTX octx; } HMAC_scrypt_SHA256_CTX; void scrypt_SHA256_Init(scrypt_SHA256_CTX *); void scrypt_SHA256_Update(scrypt_SHA256_CTX *, const void *, size_t); void scrypt_SHA256_Final(unsigned char [32], scrypt_SHA256_CTX *); void HMAC_scrypt_SHA256_Init(HMAC_scrypt_SHA256_CTX *, const void *, size_t); void HMAC_scrypt_SHA256_Update(HMAC_scrypt_SHA256_CTX *, const void *, size_t); void HMAC_scrypt_SHA256_Final(unsigned char [32], HMAC_scrypt_SHA256_CTX *); /** * PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-scrypt_SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). */ void PBKDF2_scrypt_SHA256(const uint8_t *, size_t, const uint8_t *, size_t, uint64_t, uint8_t *, size_t); #endif /* !_scrypt_SHA256_H_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/crypto/crypto_scrypt.h0000644000175000017500000000404211767303130022456 0ustar micahmicah/*- * 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 /** * 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_ */ python-scrypt-0.6.1/scrypt-1.1.6/lib/crypto/crypto_aesctr.c0000644000175000017500000000671411767303130022416 0ustar micahmicah/*- * Copyright 2007-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 "sysendian.h" #include "crypto_aesctr.h" struct crypto_aesctr { 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(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); AES_encrypt(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; /* Zero potentially sensitive information. */ for (i = 0; i < 16; i++) stream->buf[i] = 0; stream->bytectr = stream->nonce = 0; /* Free the stream. */ free(stream); } python-scrypt-0.6.1/scrypt-1.1.6/lib/crypto/sha256.c0000644000175000017500000002637011767303130020545 0ustar micahmicah/*- * Copyright 2005,2007,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. */ #include "scrypt_platform.h" #include #include #include #include "sysendian.h" #include "sha256.h" /* * Encode a length len/4 vector of (uint32_t) into a length len vector of * (unsigned char) in big-endian form. Assumes len is a multiple of 4. */ static void be32enc_vect(unsigned char *dst, const uint32_t *src, size_t len) { size_t i; for (i = 0; i < len / 4; i++) be32enc(dst + i * 4, src[i]); } /* * Decode a big-endian length len vector of (unsigned char) into a length * len/4 vector of (uint32_t). Assumes len is a multiple of 4. */ static void be32dec_vect(uint32_t *dst, const unsigned char *src, size_t len) { size_t i; for (i = 0; i < len / 4; i++) dst[i] = be32dec(src + i * 4); } /* Elementary functions used by scrypt_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)) /* scrypt_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) /* * scrypt_SHA256 block compression function. The 256-bit state is transformed via * the 512-bit input block to produce a new state. */ static void scrypt_SHA256_Transform(uint32_t * state, const unsigned char 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. */ memset(W, 0, 256); memset(S, 0, 32); t0 = t1 = 0; } static unsigned char 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 scrypt_SHA256_Pad(scrypt_SHA256_CTX * ctx) { unsigned char 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. */ be32enc_vect(len, ctx->count, 8); /* Add 1--64 bytes so that the resulting length is 56 mod 64 */ r = (ctx->count[1] >> 3) & 0x3f; plen = (r < 56) ? (56 - r) : (120 - r); scrypt_SHA256_Update(ctx, PAD, (size_t)plen); /* Add the terminating bit-count */ scrypt_SHA256_Update(ctx, len, 8); } /* SHA-256 initialization. Begins a SHA-256 operation. */ void scrypt_SHA256_Init(scrypt_SHA256_CTX * ctx) { /* Zero bits processed so far */ ctx->count[0] = ctx->count[1] = 0; /* Magic initialization constants */ ctx->state[0] = 0x6A09E667; ctx->state[1] = 0xBB67AE85; ctx->state[2] = 0x3C6EF372; ctx->state[3] = 0xA54FF53A; ctx->state[4] = 0x510E527F; ctx->state[5] = 0x9B05688C; ctx->state[6] = 0x1F83D9AB; ctx->state[7] = 0x5BE0CD19; } /* Add bytes into the hash */ void scrypt_SHA256_Update(scrypt_SHA256_CTX * ctx, const void *in, size_t len) { uint32_t bitlen[2]; uint32_t r; const unsigned char *src = in; /* Number of bytes left in the buffer from previous updates */ r = (ctx->count[1] >> 3) & 0x3f; /* Convert the length into a number of bits */ bitlen[1] = ((uint32_t)len) << 3; bitlen[0] = (uint32_t)(len >> 29); /* Update number of bits */ if ((ctx->count[1] += bitlen[1]) < bitlen[1]) ctx->count[0]++; ctx->count[0] += bitlen[0]; /* 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); scrypt_SHA256_Transform(ctx->state, ctx->buf); src += 64 - r; len -= 64 - r; /* Perform complete blocks */ while (len >= 64) { scrypt_SHA256_Transform(ctx->state, src); src += 64; len -= 64; } /* Copy left over data into buffer */ memcpy(ctx->buf, src, len); } /* * SHA-256 finalization. Pads the input data, exports the hash value, * and clears the context state. */ void scrypt_SHA256_Final(unsigned char digest[32], scrypt_SHA256_CTX * ctx) { /* Add padding */ scrypt_SHA256_Pad(ctx); /* Write the hash */ be32enc_vect(digest, ctx->state, 32); /* Clear the context state */ memset((void *)ctx, 0, sizeof(*ctx)); } /* Initialize an HMAC-scrypt_SHA256 operation with the given key. */ void HMAC_scrypt_SHA256_Init(HMAC_scrypt_SHA256_CTX * ctx, const void * _K, size_t Klen) { unsigned char pad[64]; unsigned char khash[32]; const unsigned char * K = _K; size_t i; /* If Klen > 64, the key is really scrypt_SHA256(K). */ if (Klen > 64) { scrypt_SHA256_Init(&ctx->ictx); scrypt_SHA256_Update(&ctx->ictx, K, Klen); scrypt_SHA256_Final(khash, &ctx->ictx); K = khash; Klen = 32; } /* Inner scrypt_SHA256 operation is scrypt_SHA256(K xor [block of 0x36] || data). */ scrypt_SHA256_Init(&ctx->ictx); memset(pad, 0x36, 64); for (i = 0; i < Klen; i++) pad[i] ^= K[i]; scrypt_SHA256_Update(&ctx->ictx, pad, 64); /* Outer scrypt_SHA256 operation is scrypt_SHA256(K xor [block of 0x5c] || hash). */ scrypt_SHA256_Init(&ctx->octx); memset(pad, 0x5c, 64); for (i = 0; i < Klen; i++) pad[i] ^= K[i]; scrypt_SHA256_Update(&ctx->octx, pad, 64); /* Clean the stack. */ memset(khash, 0, 32); } /* Add bytes to the HMAC-scrypt_SHA256 operation. */ void HMAC_scrypt_SHA256_Update(HMAC_scrypt_SHA256_CTX * ctx, const void *in, size_t len) { /* Feed data to the inner scrypt_SHA256 operation. */ scrypt_SHA256_Update(&ctx->ictx, in, len); } /* Finish an HMAC-scrypt_SHA256 operation. */ void HMAC_scrypt_SHA256_Final(unsigned char digest[32], HMAC_scrypt_SHA256_CTX * ctx) { unsigned char ihash[32]; /* Finish the inner scrypt_SHA256 operation. */ scrypt_SHA256_Final(ihash, &ctx->ictx); /* Feed the inner hash to the outer scrypt_SHA256 operation. */ scrypt_SHA256_Update(&ctx->octx, ihash, 32); /* Finish the outer scrypt_SHA256 operation. */ scrypt_SHA256_Final(digest, &ctx->octx); /* Clean the stack. */ memset(ihash, 0, 32); } /** * PBKDF2_scrypt_SHA256(passwd, passwdlen, salt, saltlen, c, buf, dkLen): * Compute PBKDF2(passwd, salt, c, dkLen) using HMAC-scrypt_SHA256 as the PRF, and * write the output to buf. The value dkLen must be at most 32 * (2^32 - 1). */ void PBKDF2_scrypt_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_scrypt_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; /* Compute HMAC state after processing P and S. */ HMAC_scrypt_SHA256_Init(&PShctx, passwd, passwdlen); HMAC_scrypt_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_scrypt_SHA256_CTX)); HMAC_scrypt_SHA256_Update(&hctx, ivec, 4); HMAC_scrypt_SHA256_Final(U, &hctx); /* T_i = U_1 ... */ memcpy(T, U, 32); for (j = 2; j <= c; j++) { /* Compute U_j. */ HMAC_scrypt_SHA256_Init(&hctx, passwd, passwdlen); HMAC_scrypt_SHA256_Update(&hctx, U, 32); HMAC_scrypt_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. */ memset(&PShctx, 0, sizeof(HMAC_scrypt_SHA256_CTX)); } python-scrypt-0.6.1/scrypt-1.1.6/lib/crypto/crypto_aesctr.h0000644000175000017500000000447311767303130022423 0ustar micahmicah/*- * 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_AESCTR_H_ #define _CRYPTO_AESCTR_H_ #include #include /** * 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(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 *); #endif /* !_CRYPTO_AESCTR_H_ */ python-scrypt-0.6.1/tests/0000755000175000017500000000000012134477552014461 5ustar micahmicahpython-scrypt-0.6.1/tests/hashvectors.csv0000644000175000017500000000122312040043160017501 0ustar micahmicahpassword,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,cbc397a9b5f5a53048c5b9f039ee1246d9532c8089fb346a4ab47cd0701febf18652b1ee042e070d1b6c631c43fd05ececd5b165ee1c2ffc1a2e98406fc2cd52python-scrypt-0.6.1/tests/test_scrypt_py2x.py0000644000175000017500000000345712040043160020365 0ustar micahmicah# -*- coding: utf-8 -*- from sys import version_info 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) import scrypt @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() python-scrypt-0.6.1/tests/test_scrypt.py0000644000175000017500000002766412040212602017410 0ustar micahmicah# -*- coding: utf-8 -*- from os import urandom from os.path import dirname, abspath, sep from sys import version_info from csv import reader from binascii import a2b_hex, b2a_hex import base64 import json 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) import scrypt 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() python-scrypt-0.6.1/tests/__init__.py0000644000175000017500000000000011767303130016547 0ustar micahmicahpython-scrypt-0.6.1/tests/test_scrypt_py3x.py0000644000175000017500000000371612040043160020364 0ustar micahmicah# -*- coding: utf-8 -*- from sys import version_info 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) import scrypt @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() python-scrypt-0.6.1/tests/ciphertexts.csv0000644000175000017500000000310112040043160017507 0ustar micahmicahinput,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,736372797074000a0000000800000014e53c55cd89b6e2de639c1621d92e79212e5f4fc793387435486427eb8adeb192382b5b6397f98ac66fa528a13cba01bd611082369fe1e2244a01ba8329ff6fcaa2db5e87fb75683ae6fc636d873c2e004a0209b947c7b8e805174d65ec0ac2cb597baadae6cf092c33a5096590860b51570faa89e39bf0python-scrypt-0.6.1/README.rst0000644000175000017500000001022712040215424014770 0ustar micahmicah========================= 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 randstr(length): return ''.join(chr(random.randint(0,255)) for i in range(length)) def hash_password(password, maxtime=0.5, datalength=64): return scrypt.encrypt(randstr(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. 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-scrypt-0.6.1/setup.py0000644000175000017500000001033412134477540015027 0ustar micahmicah#!/usr/bin/env python from distutils.core import setup, Extension, Command import sys import platform includes = [] library_dirs = [] cmdclasses = dict() CFLAGS = [] class Tester(Command): """Runs unit tests""" user_options = [] def initialize_options(self): pass def finalize_options(self): pass def run(self): if ((sys.version_info > (3, 2, 0, 'final', 0)) or (sys.version_info > (2, 7, 0, 'final', 0) and sys.version_info < (3, 0, 0, 'final', 0))): from unittest import TextTestRunner, defaultTestLoader else: try: from unittest2 import TextTestRunner, defaultTestLoader except ImportError: print("Please install unittest2 to run the test suite") exit(-1) from tests import test_scrypt, test_scrypt_py2x, test_scrypt_py3x suite = defaultTestLoader.loadTestsFromModule(test_scrypt) suite.addTests(defaultTestLoader.loadTestsFromModule(test_scrypt_py2x)) suite.addTests(defaultTestLoader.loadTestsFromModule(test_scrypt_py3x)) runner = TextTestRunner() result = runner.run(suite) cmdclasses['test'] = Tester 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 = [] library_dirs = ['c:\OpenSSL-Win32\lib\MinGW'] libraries = ['eay32'] includes = ['c:\OpenSSL-Win32\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.1.6/lib/crypto/crypto_aesctr.c', 'scrypt-1.1.6/lib/crypto/crypto_scrypt-nosse.c', 'scrypt-1.1.6/lib/crypto/sha256.c', 'scrypt-1.1.6/lib/scryptenc/scryptenc.c', 'scrypt-1.1.6/lib/scryptenc/scryptenc_cpuperf.c', 'scrypt-1.1.6/lib/util/memlimit.c', 'scrypt-1.1.6/lib/util/warn.c'], include_dirs=['scrypt-1.1.6', 'scrypt-1.1.6/lib', 'scrypt-1.1.6/lib/scryptenc', 'scrypt-1.1.6/lib/crypto', 'scrypt-1.1.6/lib/util'] + includes, define_macros=[('HAVE_CONFIG_H', None)] + define_macros, extra_compile_args=CFLAGS, library_dirs=library_dirs, libraries=libraries) setup(name='scrypt', version='0.6.1', 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.6', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3', 'Topic :: Security :: Cryptography', 'Topic :: Software Development :: Libraries'], license='2-clause BSD', long_description=open('README.rst').read(), cmdclass=cmdclasses)