"""Deterministic hashing utilities shared between the Python prototype and the TypeScript web port. Every function here is specified to be bit-identical to its TypeScript counterpart (see web demo ``src/lib/spira/hashing.ts``). All arithmetic is 64-bit unsigned wrapped (Python ints / BigInt in TS) or 32-bit unsigned where noted. No platform-dependent behaviour is allowed in this module. """ from __future__ import annotations MASK32 = 0xFFFFFFFF MASK64 = 0xFFFFFFFFFFFFFFFF FNV_OFFSET_BASIS = 0xCBF29CE484222325 FNV_PRIME_64 = 0x100000001B3 # Salts for hippocampal lane keys (one per context slot). LANE_SALTS = ( 0x9E3779B97F4A7C15, 0xBF58476D1CE4E5B9, 0x94D049BB133111EB, 0x2545F4914F6DDC1D, ) def fnv1a64(data: bytes, seed: int = 0) -> int: """FNV-1a 64-bit hash of a byte string, with an optional seed XORed into the offset basis. Used to content-address EPT patches.""" h = (FNV_OFFSET_BASIS ^ (seed & MASK64)) & MASK64 for b in data: h ^= b h = (h * FNV_PRIME_64) & MASK64 return h def splitmix64(x: int) -> int: """splitmix64 finalizer (MurmurHash3 helper). 64-bit in, 64-bit out.""" z = (x + 0x9E3779B97F4A7C15) & MASK64 z = ((z ^ (z >> 30)) * 0xBF58476D1CE4E5B9) & MASK64 z = ((z ^ (z >> 27)) * 0x94D049BB133111EB) & MASK64 return (z ^ (z >> 31)) & MASK64 def lane_key32(patch_id: int, lane: int) -> int: """32-bit key for one hippocampal lane (context slot ``lane``). High 32 bits of splitmix64 give excellent avalanche while staying representable as a JS ``number`` (via >>> ops) in the TypeScript port. """ return splitmix64(patch_id ^ LANE_SALTS[lane]) >> 32 class Mulberry32: """mulberry32 PRNG (bryc, public domain). Produces the exact same float sequence as the TS implementation, so network weights regenerated from a seed are bit-identical across languages. Returns uniforms in [0, 1). """ __slots__ = ("state",) def __init__(self, seed: int) -> None: self.state = seed & MASK32 def next_float(self) -> float: self.state = (self.state + 0x6D2B79F5) & MASK32 t = self.state t = ((t ^ (t >> 15)) * (t | 1)) & MASK32 t = (t ^ (t + ((((t ^ (t >> 7)) * (t | 61)) & MASK32)))) & MASK32 return ((t ^ (t >> 14)) & MASK32) / 4294967296.0 def next_weight(self, scale: float) -> float: """Symmetric uniform weight in [-scale, scale].""" return (self.next_float() * 2.0 - 1.0) * scale def input_neurons(patch_id: int, d_in: int, k_in: int) -> list[int]: """Map a patch id to ``k_in`` input-neuron indices (hashing trick). No embedding table: the projection is a pure function of the patch id, so any patch ever seen (or never seen) projects consistently. """ out = [] for j in range(k_in): h = splitmix64(patch_id ^ (0x51ED270B733D4C31 + j * 0x9E3779B97F4A7C15)) out.append((h >> 32) % d_in) return out