Esempio n. 1
0
def pbkdf2(passwd,
           salt,
           hashtype=HashTypes.SHA2,
           iterations=10000,
           dklen=None):
    """
    Derive a bytes-like key from a string password using the specified
    hash.  salt is bytes-like.  Greater iterations provide greater security.
    If dklen is specified, it must be an int.
    """
    if isinstance(passwd, str):
        passwd = passwd.encode()
    check_hashtype(hashtype)
    if hashtype == HashTypes.SHA1:
        hash_name = 'sha1'
    elif hashtype == HashTypes.SHA2:
        hash_name = 'sha256'
    elif hashtype == HashTypes.SHA3:
        hash_name = 'sha3_256'
    elif hashtype == HashTypes.BLAKE2B:
        hash_name = 'blake2b'

    # blake2b gets "unsupported hash type"
    if sys.version_info >= (3, 6):
        # hash_name is str like 'sha1' or 'sha256'
        #     LIMITATION: 'sha3', variations, and 'blake2b' are NOT SUPPORTED
        # passwd must be bytes-like
        return _pbkdf2(hash_name, passwd, salt, iterations, dklen)

    else:
        if not dklen:
            dklen = 32  # just playing around
        return PBKDF2(passwd, salt, iterations=iterations).read(dklen)
Esempio n. 2
0
def scrypt(password, salt, N=SCRYPT_N, r=SCRYPT_r, p=SCRYPT_p, olen=64):
    """Returns a key derived using the scrypt key-derivarion function

    N must be a power of two larger than 1 but no larger than 2 ** 63 (insane)
    r and p must be positive numbers such that r * p < 2 ** 30

    The default values are:
    N -- 2**14 (~16k)
    r -- 8
    p -- 1

    Memory usage is proportional to N*r. Defaults require about 16 MiB.
    Time taken is proportional to N*p. Defaults take <100ms of a recent x86.

    The last one differs from libscrypt defaults, but matches the 'interactive'
    work factor from the original paper. For long term storage where runtime of
    key derivation is not a problem, you could use 16 as in libscrypt or better
    yet increase N if memory is plentiful.
    """

    check_args(password, salt, N, r, p, olen)

    # Everything is lists of 32-bit uints for all but pbkdf2
    try:
        B = _pbkdf2('sha256', password, salt, 1, p * 128 * r)
        B = list(struct.unpack('<%dI' % (len(B) // 4), B))
        XY = [0] * (64 * r)
        V = [0] * (32 * r * N)
    except (MemoryError, OverflowError):
        raise ValueError("scrypt parameters don't fit in memory")

    for i in xrange(p):
        smix(B, i * 32 * r, r, N, V, XY)

    B = struct.pack('<%dI' % len(B), *B)
    return _pbkdf2('sha256', password, B, 1, olen)
Esempio n. 3
0
def scrypt(password, salt, N=SCRYPT_N, r=SCRYPT_r, p=SCRYPT_p, olen=64):
    """Returns a key derived using the scrypt key-derivarion function

    N must be a power of two larger than 1 but no larger than 2 ** 63 (insane)
    r and p must be positive numbers such that r * p < 2 ** 30

    The default values are:
    N -- 2**14 (~16k)
    r -- 8
    p -- 1

    Memory usage is proportional to N*r. Defaults require about 16 MiB.
    Time taken is proportional to N*p. Defaults take <100ms of a recent x86.

    The last one differs from libscrypt defaults, but matches the 'interactive'
    work factor from the original paper. For long term storage where runtime of
    key derivation is not a problem, you could use 16 as in libscrypt or better
    yet increase N if memory is plentiful.
    """

    check_args(password, salt, N, r, p, olen)

    # Everything is lists of 32-bit uints for all but pbkdf2
    try:
        B  = _pbkdf2('sha256', password, salt, 1, p * 128 * r)
        B  = list(struct.unpack('<%dI' % (len(B) // 4), B))
        XY = [0] * (64 * r)
        V  = [0] * (32 * r * N)
    except (MemoryError, OverflowError):
        raise ValueError("scrypt parameters don't fit in memory")

    for i in xrange(p):
        smix(B, i * 32 * r, r, N, V, XY)

    B = struct.pack('<%dI' % len(B), *B)
    return _pbkdf2('sha256', password, B, 1, olen)
def scrypt(password, salt, N=SCRYPT_N, r=SCRYPT_r, p=SCRYPT_p, olen=64):
    """Returns a key derived using the scrypt key-derivarion function

    N must be a power of two larger than 1 but no larger than 2 ** 63 (insane)
    r and p must be positive numbers such that r * p < 2 ** 30

    The default values are:
    N -- 2**14 (~16k)
    r -- 8
    p -- 1

    Memory usage is proportional to N*r. Defaults require about 16 MiB.
    Time taken is proportional to N*p. Defaults take <100ms of a recent x86.

    The last one differs from libscrypt defaults, but matches the 'interactive'
    work factor from the original paper. For long term storage where runtime of
    key derivation is not a problem, you could use 16 as in libscrypt or better
    yet increase N if memory is plentiful.
    """
    def array_overwrite(source, s_start, dest, d_start, length):
        dest[d_start:d_start + length] = source[s_start:s_start + length]


    def blockxor(source, s_start, dest, d_start, length):
        for i in xrange(length):
            dest[d_start + i] ^= source[s_start + i]


    def integerify(B, r):
        """A bijection from ({0, 1} ** k) to {0, ..., (2 ** k) - 1"""

        Bi = (2 * r - 1) * 8
        return B[Bi] & 0xffffffff


    def salsa20_8(B, x):
        """Salsa 20/8 using libsodium

        NaCL/libsodium includes crypto_core_salsa208, but unfortunately it
        expects the data in a different order, so we need to mix it up a bit.
        """
        hi = 0xffffffff00000000
        lo = 0x00000000ffffffff
        struct.pack_into('<9Q', x, 0,
            (B[0] & lo) +  (B[2] & hi),  (B[5] & lo) + (B[7] & hi), # c
            B[3], B[4],                                             # in
            B[0], B[1], (B[2] & lo) + (B[5] & hi),                  # pad k pad
            B[6], B[7],
        )

        c = ctypes.addressof(x)
        i = c + 4*4
        k = c + 9*4

        _libsodium_salsa20_8(c, i, k, c)

        B[:] = struct.unpack('<8Q8x', x)


    def blockmix_salsa8(BY, Yi, r):
        """Blockmix; Used by SMix"""

        start = (2 * r - 1) * 8
        X = BY[start:start+8]                              # BlockMix - 1
        x = ctypes.create_string_buffer(8*9)

        for i in xrange(2 * r):                            # BlockMix - 2
            blockxor(BY, i * 8, X, 0, 8)                   # BlockMix - 3(inner)
            salsa20_8(X, x)                                # BlockMix - 3(outer)
            array_overwrite(X, 0, BY, Yi + (i * 8), 8)     # BlockMix - 4

        for i in xrange(r):                                # BlockMix - 6
            array_overwrite(BY, Yi + (i * 2) * 8, BY, i * 8, 8)
            array_overwrite(BY, Yi + (i*2 + 1) * 8, BY, (i + r) * 8, 8)


    def smix(B, Bi, r, N, V, X):
        """SMix; a specific case of ROMix based on Salsa20/8"""

        array_overwrite(B, Bi, X, 0, 16 * r)               # ROMix - 1

        for i in xrange(N):                                # ROMix - 2
            array_overwrite(X, 0, V, i * (16 * r), 16 * r) # ROMix - 3
            blockmix_salsa8(X, 16 * r, r)                  # ROMix - 4

        for i in xrange(N):                                # ROMix - 6
            j = integerify(X, r) & (N - 1)                 # ROMix - 7
            blockxor(V, j * (16 * r), X, 0, 16 * r)        # ROMix - 8(inner)
            blockmix_salsa8(X, 16 * r, r)                  # ROMix - 9(outer)

        array_overwrite(X, 0, B, Bi, 16 * r)               # ROMix - 10

    check_args(password, salt, N, r, p, olen)

    # Everything is lists of 64-bit uints for all but pbkdf2
    try:
        B  = _pbkdf2('sha256', password, salt, 1, p * 128 * r)
        B  = list(struct.unpack('<%dQ' % (len(B) // 8), B))
        XY = [0] * (32 * r)
        V  = [0] * (16 * r * N)
    except (MemoryError, OverflowError):
        raise ValueError("scrypt parameters don't fit in memory")

    for i in xrange(p):
        smix(B, i * 16 * r, r, N, V, XY)

    B = struct.pack('<%dQ' % len(B), *B)
    return _pbkdf2('sha256', password, B, 1, olen)