mirror of
https://gitlab.com/MoonTestUse1/AdministrationItDepartmens.git
synced 2025-08-14 00:25:46 +02:00
Initial commit
This commit is contained in:
281
venv/Lib/site-packages/passlib/crypto/scrypt/__init__.py
Normal file
281
venv/Lib/site-packages/passlib/crypto/scrypt/__init__.py
Normal file
@@ -0,0 +1,281 @@
|
||||
"""
|
||||
passlib.utils.scrypt -- scrypt hash frontend and help utilities
|
||||
|
||||
XXX: add this module to public docs?
|
||||
"""
|
||||
#==========================================================================
|
||||
# imports
|
||||
#==========================================================================
|
||||
from __future__ import absolute_import
|
||||
# core
|
||||
import logging; log = logging.getLogger(__name__)
|
||||
from warnings import warn
|
||||
# pkg
|
||||
from passlib import exc
|
||||
from passlib.utils import to_bytes
|
||||
from passlib.utils.compat import PYPY
|
||||
# local
|
||||
__all__ =[
|
||||
"validate",
|
||||
"scrypt",
|
||||
]
|
||||
|
||||
#==========================================================================
|
||||
# config validation
|
||||
#==========================================================================
|
||||
|
||||
#: internal global constant for setting stdlib scrypt's maxmem (int bytes).
|
||||
#: set to -1 to auto-calculate (see _load_stdlib_backend() below)
|
||||
#: set to 0 for openssl default (32mb according to python docs)
|
||||
#: TODO: standardize this across backends, and expose support via scrypt hash config;
|
||||
#: currently not very configurable, and only applies to stdlib backend.
|
||||
SCRYPT_MAXMEM = -1
|
||||
|
||||
#: max output length in bytes
|
||||
MAX_KEYLEN = ((1 << 32) - 1) * 32
|
||||
|
||||
#: max ``r * p`` limit
|
||||
MAX_RP = (1 << 30) - 1
|
||||
|
||||
# TODO: unittests for this function
|
||||
def validate(n, r, p):
|
||||
"""
|
||||
helper which validates a set of scrypt config parameters.
|
||||
scrypt will take ``O(n * r * p)`` time and ``O(n * r)`` memory.
|
||||
limitations are that ``n = 2**<positive integer>``, ``n < 2**(16*r)``, ``r * p < 2 ** 30``.
|
||||
|
||||
:param n: scrypt rounds
|
||||
:param r: scrypt block size
|
||||
:param p: scrypt parallel factor
|
||||
"""
|
||||
if r < 1:
|
||||
raise ValueError("r must be > 0: r=%r" % r)
|
||||
|
||||
if p < 1:
|
||||
raise ValueError("p must be > 0: p=%r" % p)
|
||||
|
||||
if r * p > MAX_RP:
|
||||
# pbkdf2-hmac-sha256 limitation - it will be requested to generate ``p*(2*r)*64`` bytes,
|
||||
# but pbkdf2 can do max of (2**31-1) blocks, and sha-256 has 32 byte block size...
|
||||
# so ``(2**31-1)*32 >= p*r*128`` -> ``r*p < 2**30``
|
||||
raise ValueError("r * p must be < 2**30: r=%r, p=%r" % (r,p))
|
||||
|
||||
if n < 2 or n & (n - 1):
|
||||
raise ValueError("n must be > 1, and a power of 2: n=%r" % n)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
UINT32_SIZE = 4
|
||||
|
||||
|
||||
def estimate_maxmem(n, r, p, fudge=1.05):
|
||||
"""
|
||||
calculate memory required for parameter combination.
|
||||
assumes parameters have already been validated.
|
||||
|
||||
.. warning::
|
||||
this is derived from OpenSSL's scrypt maxmem formula;
|
||||
and may not be correct for other implementations
|
||||
(additional buffers, different parallelism tradeoffs, etc).
|
||||
"""
|
||||
# XXX: expand to provide upper bound for diff backends, or max across all of them?
|
||||
# NOTE: openssl's scrypt() enforces it's maxmem parameter based on calc located at
|
||||
# <openssl/providers/default/kdfs/scrypt.c>, ending in line containing "Blen + Vlen > maxmem"
|
||||
# using the following formula:
|
||||
# Blen = p * 128 * r
|
||||
# Vlen = 32 * r * (N + 2) * sizeof(uint32_t)
|
||||
# total_bytes = Blen + Vlen
|
||||
maxmem = r * (128 * p + 32 * (n + 2) * UINT32_SIZE)
|
||||
# add fudge factor so we don't have off-by-one mismatch w/ openssl
|
||||
maxmem = int(maxmem * fudge)
|
||||
return maxmem
|
||||
|
||||
|
||||
# TODO: configuration picker (may need psutil for full effect)
|
||||
|
||||
#==========================================================================
|
||||
# hash frontend
|
||||
#==========================================================================
|
||||
|
||||
#: backend function used by scrypt(), filled in by _set_backend()
|
||||
_scrypt = None
|
||||
|
||||
#: name of backend currently in use, exposed for informational purposes.
|
||||
backend = None
|
||||
|
||||
def scrypt(secret, salt, n, r, p=1, keylen=32):
|
||||
"""run SCrypt key derivation function using specified parameters.
|
||||
|
||||
:arg secret:
|
||||
passphrase string (unicode is encoded to bytes using utf-8).
|
||||
|
||||
:arg salt:
|
||||
salt string (unicode is encoded to bytes using utf-8).
|
||||
|
||||
:arg n:
|
||||
integer 'N' parameter
|
||||
|
||||
:arg r:
|
||||
integer 'r' parameter
|
||||
|
||||
:arg p:
|
||||
integer 'p' parameter
|
||||
|
||||
:arg keylen:
|
||||
number of bytes of key to generate.
|
||||
defaults to 32 (the internal block size).
|
||||
|
||||
:returns:
|
||||
a *keylen*-sized bytes instance
|
||||
|
||||
SCrypt imposes a number of constraints on it's input parameters:
|
||||
|
||||
* ``r * p < 2**30`` -- due to a limitation of PBKDF2-HMAC-SHA256.
|
||||
* ``keylen < (2**32 - 1) * 32`` -- due to a limitation of PBKDF2-HMAC-SHA256.
|
||||
* ``n`` must a be a power of 2, and > 1 -- internal limitation of scrypt() implementation
|
||||
|
||||
:raises ValueError: if the provided parameters are invalid (see constraints above).
|
||||
|
||||
.. warning::
|
||||
|
||||
Unless the third-party ``scrypt <https://pypi.python.org/pypi/scrypt/>``_ package
|
||||
is installed, passlib will use a builtin pure-python implementation of scrypt,
|
||||
which is *considerably* slower (and thus requires a much lower / less secure
|
||||
``n`` value in order to be usuable). Installing the :mod:`!scrypt` package
|
||||
is strongly recommended.
|
||||
"""
|
||||
validate(n, r, p)
|
||||
secret = to_bytes(secret, param="secret")
|
||||
salt = to_bytes(salt, param="salt")
|
||||
if keylen < 1:
|
||||
raise ValueError("keylen must be at least 1")
|
||||
if keylen > MAX_KEYLEN:
|
||||
raise ValueError("keylen too large, must be <= %d" % MAX_KEYLEN)
|
||||
return _scrypt(secret, salt, n, r, p, keylen)
|
||||
|
||||
|
||||
def _load_builtin_backend():
|
||||
"""
|
||||
Load pure-python scrypt implementation built into passlib.
|
||||
"""
|
||||
slowdown = 10 if PYPY else 100
|
||||
warn("Using builtin scrypt backend, which is %dx slower than is required "
|
||||
"for adequate security. Installing scrypt support (via 'pip install scrypt') "
|
||||
"is strongly recommended" % slowdown, exc.PasslibSecurityWarning)
|
||||
from ._builtin import ScryptEngine
|
||||
return ScryptEngine.execute
|
||||
|
||||
|
||||
def _load_cffi_backend():
|
||||
"""
|
||||
Try to import the ctypes-based scrypt hash function provided by the
|
||||
``scrypt <https://pypi.python.org/pypi/scrypt/>``_ package.
|
||||
"""
|
||||
try:
|
||||
from scrypt import hash
|
||||
return hash
|
||||
except ImportError:
|
||||
pass
|
||||
# not available, but check to see if package present but outdated / not installed right
|
||||
try:
|
||||
import scrypt
|
||||
except ImportError as err:
|
||||
if "scrypt" not in str(err):
|
||||
# e.g. if cffi isn't set up right
|
||||
# user should try importing scrypt explicitly to diagnose problem.
|
||||
warn("'scrypt' package failed to import correctly (possible installation issue?)",
|
||||
exc.PasslibWarning)
|
||||
# else: package just isn't installed
|
||||
else:
|
||||
warn("'scrypt' package is too old (lacks ``hash()`` method)", exc.PasslibWarning)
|
||||
return None
|
||||
|
||||
|
||||
def _load_stdlib_backend():
|
||||
"""
|
||||
Attempt to load stdlib scrypt() implement and return wrapper.
|
||||
Returns None if not found.
|
||||
"""
|
||||
try:
|
||||
# new in python 3.6, if compiled with openssl >= 1.1
|
||||
from hashlib import scrypt as stdlib_scrypt
|
||||
except ImportError:
|
||||
return None
|
||||
|
||||
def stdlib_scrypt_wrapper(secret, salt, n, r, p, keylen):
|
||||
# work out appropriate "maxmem" parameter
|
||||
#
|
||||
# TODO: would like to enforce a single "maxmem" policy across all backends;
|
||||
# and maybe expose this via scrypt hasher config.
|
||||
#
|
||||
# for now, since parameters should all be coming from internally-controlled sources
|
||||
# (password hashes), using policy of "whatever memory the parameters needs".
|
||||
# furthermore, since stdlib scrypt is only place that needs this,
|
||||
# currently calculating exactly what maxmem needs to make things work for stdlib call.
|
||||
# as hack, this can be overriden via SCRYPT_MAXMEM above,
|
||||
# would like to formalize all of this.
|
||||
maxmem = SCRYPT_MAXMEM
|
||||
if maxmem < 0:
|
||||
maxmem = estimate_maxmem(n, r, p)
|
||||
return stdlib_scrypt(password=secret, salt=salt, n=n, r=r, p=p, dklen=keylen,
|
||||
maxmem=maxmem)
|
||||
|
||||
return stdlib_scrypt_wrapper
|
||||
|
||||
|
||||
#: list of potential backends
|
||||
backend_values = ("stdlib", "scrypt", "builtin")
|
||||
|
||||
#: dict mapping backend name -> loader
|
||||
_backend_loaders = dict(
|
||||
stdlib=_load_stdlib_backend,
|
||||
scrypt=_load_cffi_backend, # XXX: rename backend constant to "cffi"?
|
||||
builtin=_load_builtin_backend,
|
||||
)
|
||||
|
||||
|
||||
def _set_backend(name, dryrun=False):
|
||||
"""
|
||||
set backend for scrypt(). if name not specified, loads first available.
|
||||
|
||||
:raises ~passlib.exc.MissingBackendError: if backend can't be found
|
||||
|
||||
.. note:: mainly intended to be called by unittests, and scrypt hash handler
|
||||
"""
|
||||
if name == "any":
|
||||
return
|
||||
elif name == "default":
|
||||
for name in backend_values:
|
||||
try:
|
||||
return _set_backend(name, dryrun=dryrun)
|
||||
except exc.MissingBackendError:
|
||||
continue
|
||||
raise exc.MissingBackendError("no scrypt backends available")
|
||||
else:
|
||||
loader = _backend_loaders.get(name)
|
||||
if not loader:
|
||||
raise ValueError("unknown scrypt backend: %r" % (name,))
|
||||
hash = loader()
|
||||
if not hash:
|
||||
raise exc.MissingBackendError("scrypt backend %r not available" % name)
|
||||
if dryrun:
|
||||
return
|
||||
global _scrypt, backend
|
||||
backend = name
|
||||
_scrypt = hash
|
||||
|
||||
# initialize backend
|
||||
_set_backend("default")
|
||||
|
||||
|
||||
def _has_backend(name):
|
||||
try:
|
||||
_set_backend(name, dryrun=True)
|
||||
return True
|
||||
except exc.MissingBackendError:
|
||||
return False
|
||||
|
||||
#==========================================================================
|
||||
# eof
|
||||
#==========================================================================
|
244
venv/Lib/site-packages/passlib/crypto/scrypt/_builtin.py
Normal file
244
venv/Lib/site-packages/passlib/crypto/scrypt/_builtin.py
Normal file
@@ -0,0 +1,244 @@
|
||||
"""passlib.utils.scrypt._builtin -- scrypt() kdf in pure-python"""
|
||||
#==========================================================================
|
||||
# imports
|
||||
#==========================================================================
|
||||
# core
|
||||
import operator
|
||||
import struct
|
||||
# pkg
|
||||
from passlib.utils.compat import izip
|
||||
from passlib.crypto.digest import pbkdf2_hmac
|
||||
from passlib.crypto.scrypt._salsa import salsa20
|
||||
# local
|
||||
__all__ =[
|
||||
"ScryptEngine",
|
||||
]
|
||||
|
||||
#==========================================================================
|
||||
# scrypt engine
|
||||
#==========================================================================
|
||||
class ScryptEngine(object):
|
||||
"""
|
||||
helper class used to run scrypt kdf, see scrypt() for frontend
|
||||
|
||||
.. warning::
|
||||
this class does NO validation of the input ranges or types.
|
||||
|
||||
it's not intended to be used directly,
|
||||
but only as a backend for :func:`passlib.utils.scrypt.scrypt()`.
|
||||
"""
|
||||
#=================================================================
|
||||
# instance attrs
|
||||
#=================================================================
|
||||
|
||||
# primary scrypt config parameters
|
||||
n = 0
|
||||
r = 0
|
||||
p = 0
|
||||
|
||||
# derived values & objects
|
||||
smix_bytes = 0
|
||||
iv_bytes = 0
|
||||
bmix_len = 0
|
||||
bmix_half_len = 0
|
||||
bmix_struct = None
|
||||
integerify = None
|
||||
|
||||
#=================================================================
|
||||
# frontend
|
||||
#=================================================================
|
||||
@classmethod
|
||||
def execute(cls, secret, salt, n, r, p, keylen):
|
||||
"""create engine & run scrypt() hash calculation"""
|
||||
return cls(n, r, p).run(secret, salt, keylen)
|
||||
|
||||
#=================================================================
|
||||
# init
|
||||
#=================================================================
|
||||
def __init__(self, n, r, p):
|
||||
# store config
|
||||
self.n = n
|
||||
self.r = r
|
||||
self.p = p
|
||||
self.smix_bytes = r << 7 # num bytes in smix input - 2*r*16*4
|
||||
self.iv_bytes = self.smix_bytes * p
|
||||
self.bmix_len = bmix_len = r << 5 # length of bmix block list - 32*r integers
|
||||
self.bmix_half_len = r << 4
|
||||
assert struct.calcsize("I") == 4
|
||||
self.bmix_struct = struct.Struct("<" + str(bmix_len) + "I")
|
||||
|
||||
# use optimized bmix for certain cases
|
||||
if r == 1:
|
||||
self.bmix = self._bmix_1
|
||||
|
||||
# pick best integerify function - integerify(bmix_block) should
|
||||
# take last 64 bytes of block and return a little-endian integer.
|
||||
# since it's immediately converted % n, we only have to extract
|
||||
# the first 32 bytes if n < 2**32 - which due to the current
|
||||
# internal representation, is already unpacked as a 32-bit int.
|
||||
if n <= 0xFFFFffff:
|
||||
integerify = operator.itemgetter(-16)
|
||||
else:
|
||||
assert n <= 0xFFFFffffFFFFffff
|
||||
ig1 = operator.itemgetter(-16)
|
||||
ig2 = operator.itemgetter(-17)
|
||||
def integerify(X):
|
||||
return ig1(X) | (ig2(X)<<32)
|
||||
self.integerify = integerify
|
||||
|
||||
#=================================================================
|
||||
# frontend
|
||||
#=================================================================
|
||||
def run(self, secret, salt, keylen):
|
||||
"""
|
||||
run scrypt kdf for specified secret, salt, and keylen
|
||||
|
||||
.. note::
|
||||
|
||||
* time cost is ``O(n * r * p)``
|
||||
* mem cost is ``O(n * r)``
|
||||
"""
|
||||
# stretch salt into initial byte array via pbkdf2
|
||||
iv_bytes = self.iv_bytes
|
||||
input = pbkdf2_hmac("sha256", secret, salt, rounds=1, keylen=iv_bytes)
|
||||
|
||||
# split initial byte array into 'p' mflen-sized chunks,
|
||||
# and run each chunk through smix() to generate output chunk.
|
||||
smix = self.smix
|
||||
if self.p == 1:
|
||||
output = smix(input)
|
||||
else:
|
||||
# XXX: *could* use threading here, if really high p values encountered,
|
||||
# but would tradeoff for more memory usage.
|
||||
smix_bytes = self.smix_bytes
|
||||
output = b''.join(
|
||||
smix(input[offset:offset+smix_bytes])
|
||||
for offset in range(0, iv_bytes, smix_bytes)
|
||||
)
|
||||
|
||||
# stretch final byte array into output via pbkdf2
|
||||
return pbkdf2_hmac("sha256", secret, output, rounds=1, keylen=keylen)
|
||||
|
||||
#=================================================================
|
||||
# smix() helper
|
||||
#=================================================================
|
||||
def smix(self, input):
|
||||
"""run SCrypt smix function on a single input block
|
||||
|
||||
:arg input:
|
||||
byte string containing input data.
|
||||
interpreted as 32*r little endian 4 byte integers.
|
||||
|
||||
:returns:
|
||||
byte string containing output data
|
||||
derived by mixing input using n & r parameters.
|
||||
|
||||
.. note:: time & mem cost are both ``O(n * r)``
|
||||
"""
|
||||
# gather locals
|
||||
bmix = self.bmix
|
||||
bmix_struct = self.bmix_struct
|
||||
integerify = self.integerify
|
||||
n = self.n
|
||||
|
||||
# parse input into 32*r integers ('X' in scrypt source)
|
||||
# mem cost -- O(r)
|
||||
buffer = list(bmix_struct.unpack(input))
|
||||
|
||||
# starting with initial buffer contents, derive V s.t.
|
||||
# V[0]=initial_buffer ... V[i] = bmix(V[i-1], V[i-1]) ... V[n-1] = bmix(V[n-2], V[n-2])
|
||||
# final buffer contents should equal bmix(V[n-1], V[n-1])
|
||||
#
|
||||
# time cost -- O(n * r) -- n loops, bmix is O(r)
|
||||
# mem cost -- O(n * r) -- V is n-element array of r-element tuples
|
||||
# NOTE: could do time / memory tradeoff to shrink size of V
|
||||
def vgen():
|
||||
i = 0
|
||||
while i < n:
|
||||
last = tuple(buffer)
|
||||
yield last
|
||||
bmix(last, buffer)
|
||||
i += 1
|
||||
V = list(vgen())
|
||||
|
||||
# generate result from X & V.
|
||||
#
|
||||
# time cost -- O(n * r) -- loops n times, calls bmix() which has O(r) time cost
|
||||
# mem cost -- O(1) -- allocates nothing, calls bmix() which has O(1) mem cost
|
||||
get_v_elem = V.__getitem__
|
||||
n_mask = n - 1
|
||||
i = 0
|
||||
while i < n:
|
||||
j = integerify(buffer) & n_mask
|
||||
result = tuple(a ^ b for a, b in izip(buffer, get_v_elem(j)))
|
||||
bmix(result, buffer)
|
||||
i += 1
|
||||
|
||||
# # NOTE: we could easily support arbitrary values of ``n``, not just powers of 2,
|
||||
# # but very few implementations have that ability, so not enabling it for now...
|
||||
# if not n_is_log_2:
|
||||
# while i < n:
|
||||
# j = integerify(buffer) % n
|
||||
# tmp = tuple(a^b for a,b in izip(buffer, get_v_elem(j)))
|
||||
# bmix(tmp,buffer)
|
||||
# i += 1
|
||||
|
||||
# repack tmp
|
||||
return bmix_struct.pack(*buffer)
|
||||
|
||||
#=================================================================
|
||||
# bmix() helper
|
||||
#=================================================================
|
||||
def bmix(self, source, target):
|
||||
"""
|
||||
block mixing function used by smix()
|
||||
uses salsa20/8 core to mix block contents.
|
||||
|
||||
:arg source:
|
||||
source to read from.
|
||||
should be list of 32*r 4-byte integers
|
||||
(2*r salsa20 blocks).
|
||||
|
||||
:arg target:
|
||||
target to write to.
|
||||
should be list with same size as source.
|
||||
the existing value of this buffer is ignored.
|
||||
|
||||
.. warning::
|
||||
|
||||
this operates *in place* on target,
|
||||
so source & target should NOT be same list.
|
||||
|
||||
.. note::
|
||||
|
||||
* time cost is ``O(r)`` -- loops 16*r times, salsa20() has ``O(1)`` cost.
|
||||
|
||||
* memory cost is ``O(1)`` -- salsa20() uses 16 x uint4,
|
||||
all other operations done in-place.
|
||||
"""
|
||||
## assert source is not target
|
||||
# Y[-1] = B[2r-1], Y[i] = hash( Y[i-1] xor B[i])
|
||||
# B' <-- (Y_0, Y_2 ... Y_{2r-2}, Y_1, Y_3 ... Y_{2r-1}) */
|
||||
half = self.bmix_half_len # 16*r out of 32*r - start of Y_1
|
||||
tmp = source[-16:] # 'X' in scrypt source
|
||||
siter = iter(source)
|
||||
j = 0
|
||||
while j < half:
|
||||
jn = j+16
|
||||
target[j:jn] = tmp = salsa20(a ^ b for a, b in izip(tmp, siter))
|
||||
target[half+j:half+jn] = tmp = salsa20(a ^ b for a, b in izip(tmp, siter))
|
||||
j = jn
|
||||
|
||||
def _bmix_1(self, source, target):
|
||||
"""special bmix() method optimized for ``r=1`` case"""
|
||||
B = source[16:]
|
||||
target[:16] = tmp = salsa20(a ^ b for a, b in izip(B, iter(source)))
|
||||
target[16:] = salsa20(a ^ b for a, b in izip(tmp, B))
|
||||
|
||||
#=================================================================
|
||||
# eoc
|
||||
#=================================================================
|
||||
|
||||
#==========================================================================
|
||||
# eof
|
||||
#==========================================================================
|
154
venv/Lib/site-packages/passlib/crypto/scrypt/_gen_files.py
Normal file
154
venv/Lib/site-packages/passlib/crypto/scrypt/_gen_files.py
Normal file
@@ -0,0 +1,154 @@
|
||||
"""passlib.utils.scrypt._gen_files - meta script that generates _salsa.py"""
|
||||
#==========================================================================
|
||||
# imports
|
||||
#==========================================================================
|
||||
# core
|
||||
import os
|
||||
# pkg
|
||||
# local
|
||||
#==========================================================================
|
||||
# constants
|
||||
#==========================================================================
|
||||
|
||||
_SALSA_OPS = [
|
||||
# row = (target idx, source idx 1, source idx 2, rotate)
|
||||
# interpreted as salsa operation over uint32...
|
||||
# target = (source1+source2)<<rotate
|
||||
|
||||
##/* Operate on columns. */
|
||||
##define R(a,b) (((a) << (b)) | ((a) >> (32 - (b))))
|
||||
##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);
|
||||
( 4, 0, 12, 7),
|
||||
( 8, 4, 0, 9),
|
||||
( 12, 8, 4, 13),
|
||||
( 0, 12, 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);
|
||||
( 9, 5, 1, 7),
|
||||
( 13, 9, 5, 9),
|
||||
( 1, 13, 9, 13),
|
||||
( 5, 1, 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);
|
||||
( 14, 10, 6, 7),
|
||||
( 2, 14, 10, 9),
|
||||
( 6, 2, 14, 13),
|
||||
( 10, 6, 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);
|
||||
( 3, 15, 11, 7),
|
||||
( 7, 3, 15, 9),
|
||||
( 11, 7, 3, 13),
|
||||
( 15, 11, 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);
|
||||
( 1, 0, 3, 7),
|
||||
( 2, 1, 0, 9),
|
||||
( 3, 2, 1, 13),
|
||||
( 0, 3, 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);
|
||||
( 6, 5, 4, 7),
|
||||
( 7, 6, 5, 9),
|
||||
( 4, 7, 6, 13),
|
||||
( 5, 4, 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);
|
||||
( 11, 10, 9, 7),
|
||||
( 8, 11, 10, 9),
|
||||
( 9, 8, 11, 13),
|
||||
( 10, 9, 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);
|
||||
( 12, 15, 14, 7),
|
||||
( 13, 12, 15, 9),
|
||||
( 14, 13, 12, 13),
|
||||
( 15, 14, 13, 18),
|
||||
]
|
||||
|
||||
def main():
|
||||
target = os.path.join(os.path.dirname(__file__), "_salsa.py")
|
||||
fh = file(target, "w")
|
||||
write = fh.write
|
||||
|
||||
VNAMES = ["v%d" % i for i in range(16)]
|
||||
|
||||
PAD = " " * 4
|
||||
PAD2 = " " * 8
|
||||
PAD3 = " " * 12
|
||||
TLIST = ", ".join("b%d" % i for i in range(16))
|
||||
VLIST = ", ".join(VNAMES)
|
||||
kwds = dict(
|
||||
VLIST=VLIST,
|
||||
TLIST=TLIST,
|
||||
)
|
||||
|
||||
write('''\
|
||||
"""passlib.utils.scrypt._salsa - salsa 20/8 core, autogenerated by _gen_salsa.py"""
|
||||
#=================================================================
|
||||
# salsa function
|
||||
#=================================================================
|
||||
|
||||
def salsa20(input):
|
||||
\"""apply the salsa20/8 core to the provided input
|
||||
|
||||
:args input: input list containing 16 32-bit integers
|
||||
:returns: result list containing 16 32-bit integers
|
||||
\"""
|
||||
|
||||
%(TLIST)s = input
|
||||
%(VLIST)s = \\
|
||||
%(TLIST)s
|
||||
|
||||
i = 0
|
||||
while i < 4:
|
||||
''' % kwds)
|
||||
|
||||
for idx, (target, source1, source2, rotate) in enumerate(_SALSA_OPS):
|
||||
write('''\
|
||||
# salsa op %(idx)d: [%(it)d] ^= ([%(is1)d]+[%(is2)d])<<<%(rot1)d
|
||||
t = (%(src1)s + %(src2)s) & 0xffffffff
|
||||
%(dst)s ^= ((t & 0x%(rmask)08x) << %(rot1)d) | (t >> %(rot2)d)
|
||||
|
||||
''' % dict(
|
||||
idx=idx, is1 = source1, is2=source2, it=target,
|
||||
src1=VNAMES[source1],
|
||||
src2=VNAMES[source2],
|
||||
dst=VNAMES[target],
|
||||
rmask=(1<<(32-rotate))-1,
|
||||
rot1=rotate,
|
||||
rot2=32-rotate,
|
||||
))
|
||||
|
||||
write('''\
|
||||
i += 1
|
||||
|
||||
''')
|
||||
|
||||
for idx in range(16):
|
||||
write(PAD + "b%d = (b%d + v%d) & 0xffffffff\n" % (idx,idx,idx))
|
||||
|
||||
write('''\
|
||||
|
||||
return %(TLIST)s
|
||||
|
||||
#=================================================================
|
||||
# eof
|
||||
#=================================================================
|
||||
''' % kwds)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
#==========================================================================
|
||||
# eof
|
||||
#==========================================================================
|
170
venv/Lib/site-packages/passlib/crypto/scrypt/_salsa.py
Normal file
170
venv/Lib/site-packages/passlib/crypto/scrypt/_salsa.py
Normal file
@@ -0,0 +1,170 @@
|
||||
"""passlib.utils.scrypt._salsa - salsa 20/8 core, autogenerated by _gen_salsa.py"""
|
||||
#=================================================================
|
||||
# salsa function
|
||||
#=================================================================
|
||||
|
||||
def salsa20(input):
|
||||
"""apply the salsa20/8 core to the provided input
|
||||
|
||||
:args input: input list containing 16 32-bit integers
|
||||
:returns: result list containing 16 32-bit integers
|
||||
"""
|
||||
|
||||
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15 = input
|
||||
v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 = \
|
||||
b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15
|
||||
|
||||
i = 0
|
||||
while i < 4:
|
||||
# salsa op 0: [4] ^= ([0]+[12])<<<7
|
||||
t = (v0 + v12) & 0xffffffff
|
||||
v4 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 1: [8] ^= ([4]+[0])<<<9
|
||||
t = (v4 + v0) & 0xffffffff
|
||||
v8 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 2: [12] ^= ([8]+[4])<<<13
|
||||
t = (v8 + v4) & 0xffffffff
|
||||
v12 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 3: [0] ^= ([12]+[8])<<<18
|
||||
t = (v12 + v8) & 0xffffffff
|
||||
v0 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
# salsa op 4: [9] ^= ([5]+[1])<<<7
|
||||
t = (v5 + v1) & 0xffffffff
|
||||
v9 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 5: [13] ^= ([9]+[5])<<<9
|
||||
t = (v9 + v5) & 0xffffffff
|
||||
v13 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 6: [1] ^= ([13]+[9])<<<13
|
||||
t = (v13 + v9) & 0xffffffff
|
||||
v1 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 7: [5] ^= ([1]+[13])<<<18
|
||||
t = (v1 + v13) & 0xffffffff
|
||||
v5 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
# salsa op 8: [14] ^= ([10]+[6])<<<7
|
||||
t = (v10 + v6) & 0xffffffff
|
||||
v14 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 9: [2] ^= ([14]+[10])<<<9
|
||||
t = (v14 + v10) & 0xffffffff
|
||||
v2 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 10: [6] ^= ([2]+[14])<<<13
|
||||
t = (v2 + v14) & 0xffffffff
|
||||
v6 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 11: [10] ^= ([6]+[2])<<<18
|
||||
t = (v6 + v2) & 0xffffffff
|
||||
v10 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
# salsa op 12: [3] ^= ([15]+[11])<<<7
|
||||
t = (v15 + v11) & 0xffffffff
|
||||
v3 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 13: [7] ^= ([3]+[15])<<<9
|
||||
t = (v3 + v15) & 0xffffffff
|
||||
v7 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 14: [11] ^= ([7]+[3])<<<13
|
||||
t = (v7 + v3) & 0xffffffff
|
||||
v11 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 15: [15] ^= ([11]+[7])<<<18
|
||||
t = (v11 + v7) & 0xffffffff
|
||||
v15 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
# salsa op 16: [1] ^= ([0]+[3])<<<7
|
||||
t = (v0 + v3) & 0xffffffff
|
||||
v1 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 17: [2] ^= ([1]+[0])<<<9
|
||||
t = (v1 + v0) & 0xffffffff
|
||||
v2 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 18: [3] ^= ([2]+[1])<<<13
|
||||
t = (v2 + v1) & 0xffffffff
|
||||
v3 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 19: [0] ^= ([3]+[2])<<<18
|
||||
t = (v3 + v2) & 0xffffffff
|
||||
v0 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
# salsa op 20: [6] ^= ([5]+[4])<<<7
|
||||
t = (v5 + v4) & 0xffffffff
|
||||
v6 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 21: [7] ^= ([6]+[5])<<<9
|
||||
t = (v6 + v5) & 0xffffffff
|
||||
v7 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 22: [4] ^= ([7]+[6])<<<13
|
||||
t = (v7 + v6) & 0xffffffff
|
||||
v4 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 23: [5] ^= ([4]+[7])<<<18
|
||||
t = (v4 + v7) & 0xffffffff
|
||||
v5 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
# salsa op 24: [11] ^= ([10]+[9])<<<7
|
||||
t = (v10 + v9) & 0xffffffff
|
||||
v11 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 25: [8] ^= ([11]+[10])<<<9
|
||||
t = (v11 + v10) & 0xffffffff
|
||||
v8 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 26: [9] ^= ([8]+[11])<<<13
|
||||
t = (v8 + v11) & 0xffffffff
|
||||
v9 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 27: [10] ^= ([9]+[8])<<<18
|
||||
t = (v9 + v8) & 0xffffffff
|
||||
v10 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
# salsa op 28: [12] ^= ([15]+[14])<<<7
|
||||
t = (v15 + v14) & 0xffffffff
|
||||
v12 ^= ((t & 0x01ffffff) << 7) | (t >> 25)
|
||||
|
||||
# salsa op 29: [13] ^= ([12]+[15])<<<9
|
||||
t = (v12 + v15) & 0xffffffff
|
||||
v13 ^= ((t & 0x007fffff) << 9) | (t >> 23)
|
||||
|
||||
# salsa op 30: [14] ^= ([13]+[12])<<<13
|
||||
t = (v13 + v12) & 0xffffffff
|
||||
v14 ^= ((t & 0x0007ffff) << 13) | (t >> 19)
|
||||
|
||||
# salsa op 31: [15] ^= ([14]+[13])<<<18
|
||||
t = (v14 + v13) & 0xffffffff
|
||||
v15 ^= ((t & 0x00003fff) << 18) | (t >> 14)
|
||||
|
||||
i += 1
|
||||
|
||||
b0 = (b0 + v0) & 0xffffffff
|
||||
b1 = (b1 + v1) & 0xffffffff
|
||||
b2 = (b2 + v2) & 0xffffffff
|
||||
b3 = (b3 + v3) & 0xffffffff
|
||||
b4 = (b4 + v4) & 0xffffffff
|
||||
b5 = (b5 + v5) & 0xffffffff
|
||||
b6 = (b6 + v6) & 0xffffffff
|
||||
b7 = (b7 + v7) & 0xffffffff
|
||||
b8 = (b8 + v8) & 0xffffffff
|
||||
b9 = (b9 + v9) & 0xffffffff
|
||||
b10 = (b10 + v10) & 0xffffffff
|
||||
b11 = (b11 + v11) & 0xffffffff
|
||||
b12 = (b12 + v12) & 0xffffffff
|
||||
b13 = (b13 + v13) & 0xffffffff
|
||||
b14 = (b14 + v14) & 0xffffffff
|
||||
b15 = (b15 + v15) & 0xffffffff
|
||||
|
||||
return b0, b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15
|
||||
|
||||
#=================================================================
|
||||
# eof
|
||||
#=================================================================
|
Reference in New Issue
Block a user