Cryptographic Hash Functions

Hash functions produce fixed-size digests from arbitrary input data. MetaMUI implements both traditional and modern hash functions for various security requirements.

Available Algorithms

SHA-256

Secure Hash Algorithm 256-bit

SHA-512

Secure Hash Algorithm 512-bit

Blake2b

Fast Cryptographic Hash

Blake2s

Optimized for 32-bit Platforms

Blake3

Parallel-Friendly Hash

SHAKE-256

Extendable Output Function

Algorithm Selection Guide

For New Applications

Recommended: Blake3

For Compatibility

Use: SHA-256

For Special Requirements

Usage Examples

Basic Hashing

from metamui_crypto import SHA256, Blake3

# SHA-256
data = b"Hello, World!"
hash_sha = SHA256.hash(data)
print(f"SHA-256: {hash_sha.hex()}")

# Blake3
hash_blake = Blake3.hash(data)
print(f"Blake3: {hash_blake.hex()}")

Streaming/Incremental Hashing

from metamui_crypto import SHA256

# Create hasher
hasher = SHA256.new()

# Update with chunks
with open('large_file.bin', 'rb') as f:
    while chunk := f.read(8192):
        hasher.update(chunk)

# Get final hash
file_hash = hasher.finalize()

Keyed Hashing (MAC)

from metamui_crypto import Blake2b
import os

# Generate random key
key = os.urandom(32)

# Keyed hash (MAC)
mac = Blake2b.new(key=key)
mac.update(b"Authenticated message")
auth_tag = mac.finalize()

# Verify MAC
mac_verify = Blake2b.new(key=key)
mac_verify.update(b"Authenticated message")
if mac_verify.finalize() == auth_tag:
    print("Message authentic")

Variable Output Length

from metamui_crypto import Blake3, SHAKE256

# Blake3 with custom output length
data = b"Input data"
hash_128bit = Blake3.hash(data, length=16)  # 128 bits
hash_256bit = Blake3.hash(data, length=32)  # 256 bits
hash_512bit = Blake3.hash(data, length=64)  # 512 bits

# SHAKE-256 XOF
xof = SHAKE256.new()
xof.update(data)
output_128bit = xof.read(16)  # Read 128 bits
output_256bit = xof.read(32)  # Read another 256 bits

Parallel Hashing (Blake3)

from metamui_crypto import Blake3
import concurrent.futures

# Hash multiple files in parallel
def hash_file(filename):
    hasher = Blake3.new()
    with open(filename, 'rb') as f:
        hasher.update(f.read())
    return filename, hasher.finalize()

files = ['file1.bin', 'file2.bin', 'file3.bin']
with concurrent.futures.ThreadPoolExecutor() as executor:
    results = list(executor.map(hash_file, files))

Hash-based Key Derivation

from metamui_crypto import SHA256, Blake2b

# Simple KDF using hash
password = b"user_password"
salt = os.urandom(16)

# SHA-256 based
key_sha = SHA256.hash(salt + password)

# Blake2b with personalization
key_blake = Blake2b.hash(
    password,
    salt=salt,
    person=b"MyApp v1.0",
    length=32
)

Security Properties

Collision Resistance

| Algorithm | Collision Resistance | Preimage Resistance | |———–|———————|——————-| | SHA-256 | 128 bits | 256 bits | | SHA-512 | 256 bits | 512 bits | | Blake2b-512 | 256 bits | 512 bits | | Blake2s-256 | 128 bits | 256 bits | | Blake3 | 128 bits minimum | 256 bits | | SHAKE-256 | min(d/2, 256) bits | d bits |

Quantum Resistance

Performance Benchmarks

Algorithm Speed (MB/s) Hardware Accelerated
Blake3 3,000 No (but parallel)
Blake2b 1,000 No
Blake2s 800 No
SHA-256 500* Yes
SHA-512 800* Yes
SHAKE-256 600 No

*With hardware acceleration

Common Use Cases

1. File Integrity

from metamui_crypto import Blake3
import json

def create_manifest(directory):
    manifest = {}
    for file in directory.iterdir():
        if file.is_file():
            hash = Blake3.hash_file(file)
            manifest[file.name] = hash.hex()
    
    with open('manifest.json', 'w') as f:
        json.dump(manifest, f)

2. Password Hashing

# Note: Use Argon2 for passwords, not raw hashes!
from metamui_crypto import Argon2

# Good: Purpose-built password hashing
password = b"user_password"
salt = os.urandom(16)
hash = Argon2.hash(password, salt)

# Bad: Don't use raw hashes for passwords
# hash = SHA256.hash(password)  # Vulnerable to attacks!

3. Digital Signatures

from metamui_crypto import Ed25519, SHA256

# Hash then sign pattern
document = b"Large document content..."
doc_hash = SHA256.hash(document)

# Sign the hash
keypair = Ed25519.generate_keypair()
signature = Ed25519.sign(doc_hash, keypair.private_key)

4. Proof of Work

from metamui_crypto import SHA256
import struct

def proof_of_work(data, difficulty):
    nonce = 0
    target = '0' * difficulty
    
    while True:
        candidate = data + struct.pack('<Q', nonce)
        hash = SHA256.hash(candidate)
        if hash.hex().startswith(target):
            return nonce, hash
        nonce += 1

Best Practices

1. Don’t Use for Passwords

# Bad: Raw hash for passwords
# password_hash = SHA256.hash(password)

# Good: Use key derivation function
from metamui_crypto import Argon2
password_hash = Argon2.hash(
    password,
    salt=salt,
    time_cost=3,
    memory_cost=65536
)

2. Include Domain Separation

# Prevent cross-protocol attacks
def hash_for_purpose(data, purpose):
    hasher = Blake3.new()
    hasher.update(purpose.encode())
    hasher.update(b'\x00')  # Separator
    hasher.update(data)
    return hasher.finalize()

# Different hashes for different purposes
signing_hash = hash_for_purpose(data, "signing")
storage_hash = hash_for_purpose(data, "storage")

3. Verify Hash Implementations

# Test with known vectors
test_vectors = {
    "": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "abc": "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad"
}

for input, expected in test_vectors.items():
    result = SHA256.hash(input.encode()).hex()
    assert result == expected

Migration Guide

From MD5/SHA-1

# Old: Broken algorithms
# import hashlib
# hash = hashlib.md5(data).hexdigest()
# hash = hashlib.sha1(data).hexdigest()

# New: Secure algorithms
from metamui_crypto import SHA256, Blake3
hash = SHA256.hash(data).hex()
# or
hash = Blake3.hash(data).hex()

Upgrading Hash Lengths

# Transitioning from SHA-256 to SHA-512
def dual_hash(data):
    # During transition, compute both
    hash_256 = SHA256.hash(data)
    hash_512 = SHA512.hash(data)
    
    # Store both, verify old, use new
    return {
        'sha256': hash_256.hex(),
        'sha512': hash_512.hex()
    }

Resources