"""SHA256Generator — SHA-256 hash computation. Ported from net.i2p.crypto.SHA256Generator. Wraps Python's hashlib.sha256. """ import hashlib from i2p_crypto.hash_data import Hash class SHA256Generator: """SHA-256 hash generator. Thread-safe (hashlib creates new state per call).""" _instance: "SHA256Generator | None" = None def __init__(self) -> None: pass @classmethod def get_instance(cls) -> "SHA256Generator": if cls._instance is None: cls._instance = SHA256Generator() return cls._instance def calculate_hash(self, source: bytes, start: int = 0, length: int = -1) -> Hash: """Calculate SHA-256 and return a Hash object.""" if length < 0: length = len(source) - start digest = hashlib.sha256(source[start : start + length]).digest() return Hash(digest) def calculate_hash_into(self, source: bytes, start: int, length: int, out: bytearray, out_offset: int) -> None: """Calculate SHA-256 into an existing buffer.""" digest = hashlib.sha256(source[start : start + length]).digest() out[out_offset : out_offset + Hash.HASH_LENGTH] = digest @staticmethod def digest(data: bytes) -> bytes: """Convenience: return raw 32-byte SHA-256 digest.""" return hashlib.sha256(data).digest()