Functional Weave
Code in TypeScript

crypto.pbkdf2-sha256@1.0.0

impl/python.py

1,166 bytes · the Python implementation · view raw

import hashlib
from typing import Any, List, Sequence


def _check_bytes(value: Any, name: str) -> bytes:
    if isinstance(value, (str, dict)) or not hasattr(value, "__len__"):
        raise TypeError("%s must be a list of integers from 0 to 255" % name)
    for b in value:
        if type(b) is not int or b < 0 or b > 255:
            raise ValueError("%s must be a list of integers from 0 to 255" % name)
    return bytes(value)


def pbkdf2_sha256(password: Sequence[int], salt: Sequence[int], iterations: int, key_length: int) -> List[int]:
    """PBKDF2-HMAC-SHA256 (RFC 8018 section 5.2), from hashlib.

    hashlib runs the iterations in C, which is what makes a six-figure
    iteration count affordable in a Python request handler.
    """
    p = _check_bytes(password, "password")
    s = _check_bytes(salt, "salt")
    if type(iterations) is not int or iterations < 1:
        raise ValueError("iterations must be a whole number of at least 1")
    if type(key_length) is not int or key_length < 1:
        raise ValueError("keyLength must be a whole number of at least 1")
    return list(hashlib.pbkdf2_hmac("sha256", p, s, iterations, key_length))