FlatHash Security-Focused API Documentation

Algorithm: FlatHash
Type: Non-Cryptographic Hash Function
Output Size: 32/64/128 bits (configurable)
Speed: Ultra-fast (designed for hash tables)
Design: Multiplication-shift with minimal collisions
Use Case: Hash tables, checksums, data structures

Table of Contents

  1. Security Contract
  2. Attack Resistance Matrix
  3. Secure Usage Examples
  4. Common Mistakes
  5. Performance vs Security
  6. Platform-Specific Notes
  7. Compliance Information

⚠️ CRITICAL WARNING

FlatHash is NOT a cryptographic hash function! It provides:

NEVER use FlatHash for:

Security Contract

hash32(data: Uint8Array, seed?: number): number

Preconditions:

Postconditions:

Side Effects:

hash64(data: Uint8Array, seed?: bigint): bigint

Preconditions:

Postconditions:

Side Effects:

hash128(data: Uint8Array, seed?: Uint8Array): Uint8Array

Preconditions:

Postconditions:

Side Effects:

Attack Resistance Matrix

❌ NO Security Against Any Attacks

Attack Type Protection Reason
Collision Finding ❌ None Trivial to find collisions
Preimage Attack ❌ None Reversible with effort
Second Preimage ❌ None Easy to construct
Length Extension ❌ None Not applicable
Differential Analysis ❌ None Predictable differences
Birthday Attack ❌ None Much worse than birthday bound

✅ Performance Characteristics

Property Performance Notes
Speed Ultra-fast ~3-5 cycles per byte
Memory Minimal No lookup tables
Parallelism Limited Sequential design
Simplicity Very simple ~10 lines of code
Distribution Good For random inputs

Secure Usage Examples

✅ CORRECT: Hash Table Implementation

import { FlatHash } from '@metamui/flathash';

class FastHashTable<K, V> {
  private buckets: Map<number, Array<[K, V]>>;
  private size: number;
  private seed: number;
  
  constructor(initialSize: number = 1024) {
    this.buckets = new Map();
    this.size = initialSize;
    this.seed = Math.floor(Math.random() * 0xFFFFFFFF);
  }
  
  private hashKey(key: K): number {
    // Convert key to bytes
    const keyBytes = this.keyToBytes(key);
    
    // Use FlatHash for bucket selection
    const hash = FlatHash.hash32(keyBytes, this.seed);
    return Math.abs(hash) % this.size;
  }
  
  set(key: K, value: V): void {
    const bucket = this.hashKey(key);
    
    if (!this.buckets.has(bucket)) {
      this.buckets.set(bucket, []);
    }
    
    const items = this.buckets.get(bucket)!;
    
    // Check for existing key
    for (let i = 0; i < items.length; i++) {
      if (this.keysEqual(items[i][0], key)) {
        items[i][1] = value;
        return;
      }
    }
    
    // Add new entry
    items.push([key, value]);
  }
  
  get(key: K): V | undefined {
    const bucket = this.hashKey(key);
    const items = this.buckets.get(bucket);
    
    if (!items) return undefined;
    
    for (const [k, v] of items) {
      if (this.keysEqual(k, key)) {
        return v;
      }
    }
    
    return undefined;
  }
  
  private keyToBytes(key: K): Uint8Array {
    if (typeof key === 'string') {
      return new TextEncoder().encode(key);
    } else if (typeof key === 'number') {
      const bytes = new Uint8Array(8);
      new DataView(bytes.buffer).setFloat64(0, key);
      return bytes;
    } else if (key instanceof Uint8Array) {
      return key;
    } else {
      // Fallback to JSON serialization
      return new TextEncoder().encode(JSON.stringify(key));
    }
  }
  
  private keysEqual(a: K, b: K): boolean {
    return a === b || JSON.stringify(a) === JSON.stringify(b);
  }
}

✅ CORRECT: Fast Checksum for Data Integrity

class DataIntegrityCheck {
  // Use FlatHash for fast, non-secure checksums
  static computeChecksum(data: Uint8Array): number {
    return FlatHash.hash32(data);
  }
  
  static verifyChecksum(data: Uint8Array, checksum: number): boolean {
    return FlatHash.hash32(data) === checksum;
  }
  
  // For network packets with error detection (not security)
  static addChecksum(packet: Uint8Array): Uint8Array {
    const checksum = FlatHash.hash32(packet);
    const result = new Uint8Array(packet.length + 4);
    
    result.set(packet, 0);
    new DataView(result.buffer).setUint32(
      packet.length,
      checksum,
      false // big-endian
    );
    
    return result;
  }
  
  static validatePacket(packet: Uint8Array): {
    valid: boolean;
    data?: Uint8Array;
  } {
    if (packet.length < 4) {
      return { valid: false };
    }
    
    const data = packet.slice(0, -4);
    const receivedChecksum = new DataView(
      packet.buffer,
      packet.byteOffset + packet.length - 4
    ).getUint32(0, false);
    
    const computedChecksum = FlatHash.hash32(data);
    
    return {
      valid: computedChecksum === receivedChecksum,
      data: computedChecksum === receivedChecksum ? data : undefined
    };
  }
}

✅ CORRECT: Cache Key Generation

class CacheKeyGenerator {
  private static seed = Date.now();
  
  static generateKey(
    method: string,
    url: string,
    params?: Record<string, any>
  ): string {
    // Combine cache key components
    const components = [
      method,
      url,
      params ? JSON.stringify(params, Object.keys(params).sort()) : ''
    ];
    
    const data = new TextEncoder().encode(components.join(':'));
    
    // Use 64-bit hash for better distribution
    const hash = FlatHash.hash64(data, BigInt(this.seed));
    
    // Convert to hex string
    return hash.toString(16);
  }
  
  // For distributed caching with multiple buckets
  static selectCacheBucket(
    key: string,
    bucketCount: number
  ): number {
    const keyBytes = new TextEncoder().encode(key);
    const hash = FlatHash.hash32(keyBytes);
    
    return Math.abs(hash) % bucketCount;
  }
}

✅ CORRECT: Bloom Filter Implementation

class BloomFilter {
  private bits: Uint8Array;
  private size: number;
  private hashCount: number;
  
  constructor(expectedItems: number, falsePositiveRate: number = 0.01) {
    // Calculate optimal size and hash count
    this.size = Math.ceil(
      -expectedItems * Math.log(falsePositiveRate) / (Math.log(2) ** 2)
    );
    this.hashCount = Math.ceil(
      this.size / expectedItems * Math.log(2)
    );
    
    this.bits = new Uint8Array(Math.ceil(this.size / 8));
  }
  
  add(item: string): void {
    const itemBytes = new TextEncoder().encode(item);
    
    // Use multiple hash functions via different seeds
    for (let i = 0; i < this.hashCount; i++) {
      const hash = FlatHash.hash32(itemBytes, i);
      const bitIndex = Math.abs(hash) % this.size;
      
      const byteIndex = Math.floor(bitIndex / 8);
      const bitOffset = bitIndex % 8;
      
      this.bits[byteIndex] |= (1 << bitOffset);
    }
  }
  
  contains(item: string): boolean {
    const itemBytes = new TextEncoder().encode(item);
    
    for (let i = 0; i < this.hashCount; i++) {
      const hash = FlatHash.hash32(itemBytes, i);
      const bitIndex = Math.abs(hash) % this.size;
      
      const byteIndex = Math.floor(bitIndex / 8);
      const bitOffset = bitIndex % 8;
      
      if ((this.bits[byteIndex] & (1 << bitOffset)) === 0) {
        return false;
      }
    }
    
    return true; // Might be false positive!
  }
}

Common Mistakes

❌ CRITICAL: Using for Security

// NEVER DO THIS - Catastrophic security failure!
function insecurePasswordStorage(password: string): number {
  // FlatHash is NOT cryptographic!
  return FlatHash.hash32(new TextEncoder().encode(password));
}

// CORRECT - Use proper password hashing
import { Argon2 } from '@metamui/argon2';

async function securePasswordStorage(password: string): Promise<Uint8Array> {
  const salt = randomBytes(16);
  return Argon2.hash(password, salt);
}

❌ Using for Message Authentication

// WRONG - No security properties!
function brokenMAC(key: Uint8Array, message: Uint8Array): number {
  const combined = new Uint8Array(key.length + message.length);
  combined.set(key, 0);
  combined.set(message, key.length);
  
  // This provides NO authentication!
  return FlatHash.hash32(combined);
}

// CORRECT - Use proper MAC
import { HMAC } from '@metamui/hmac';

function properMAC(key: Uint8Array, message: Uint8Array): Uint8Array {
  return HMAC.compute(key, message);
}

❌ Using for Unique IDs

// BAD - High collision probability
function generateId(data: string): string {
  const hash = FlatHash.hash32(new TextEncoder().encode(data));
  return hash.toString(16); // Only 32 bits!
}

// BETTER - Use proper random IDs
function generateSecureId(): string {
  return randomBytes(16).toString('hex'); // 128 bits
}

❌ Assuming Collision Resistance

// WRONG - Collisions are easy to find
class BrokenDeduplication {
  private seen = new Set<number>();
  
  isDuplicate(data: Uint8Array): boolean {
    const hash = FlatHash.hash32(data);
    
    if (this.seen.has(hash)) {
      // WRONG - Different data can have same hash!
      return true;
    }
    
    this.seen.add(hash);
    return false;
  }
}

// CORRECT - Store actual data or use cryptographic hash
class ProperDeduplication {
  private seen = new Set<string>();
  
  isDuplicate(data: Uint8Array): boolean {
    // Use cryptographic hash
    const hash = SHA256.hash(data);
    const hashHex = Buffer.from(hash).toString('hex');
    
    if (this.seen.has(hashHex)) {
      return true;
    }
    
    this.seen.add(hashHex);
    return false;
  }
}

Performance vs Security

Performance Characteristics

// Benchmark results (approximate)
// Platform: Intel i7-10700K @ 3.8GHz
// 
// FlatHash-32: ~10 GB/s
// FlatHash-64: ~8 GB/s
// FlatHash-128: ~6 GB/s
// 
// Compared to:
// SHA-256: ~300 MB/s (30x slower)
// BLAKE3: ~3 GB/s (3x slower)
// xxHash: ~15 GB/s (similar speed)

When to Use FlatHash

Use Case Suitable? Alternative
Hash tables ✅ Yes -
Checksums (non-secure) ✅ Yes CRC32
Cache keys ✅ Yes -
Bloom filters ✅ Yes -
Load balancing ✅ Yes -
Password hashing ❌ NO! Argon2
File integrity ❌ NO! SHA-256
Digital signatures ❌ NO! Ed25519
Key derivation ❌ NO! HKDF

Platform-Specific Notes

All Platforms

JavaScript/TypeScript

Embedded Systems

Compliance Information

Design Principles

Appropriate Uses

Use for:

Never use for:

Comparison with Alternatives

Algorithm Type Speed Security Use Case
FlatHash Non-crypto Fastest None Hash tables
xxHash Non-crypto Very fast None Checksums
CityHash Non-crypto Very fast None Hash tables
SHA-256 Crypto Slow High Security
BLAKE3 Crypto Fast High Security

Security Notice: FlatHash is explicitly NOT a cryptographic hash function. It provides NO security properties. Use ONLY for performance-critical, non-security applications like hash tables. For ANY security need, use SHA-256, BLAKE3, or other cryptographic functions. Report misuse to security@metamui.id

Last Updated: 2025-07-14
Version: 3.0.0
License: BSL-1.1

Security Analysis

Threat Model: FlatHash Threat Model

The comprehensive threat analysis covers:

For complete security analysis and risk assessment, see the dedicated threat model documentation.