You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
-**Per-file opcode shuffle**: Seeded Fisher-Yates (LCG) produces different instruction encodings per build. Seed + shuffle constants live in `constants.ts`.
120
131
-**Always-binary format**: All bytecode units are serialized to compact binary (`Uint8Array`) and encoded with a per-build shuffled 64-char alphabet (`A-Za-z0-9_$`). Same bit-packing as base64 (3 bytes → 4 chars) but no padding and a randomized alphabet per build. Output looks like random identifier strings. Alphabet generated via Fisher-Yates shuffle seeded from build seed. JSON serialization path has been eliminated. Runtime decoder builds a reverse lookup table from the embedded alphabet string.
121
132
-**Constant pool string encoding**: All string constants are XOR-encoded with an LCG key stream. Binary format uses `BINARY_TAG_ENCODED_STRING` (tag 11) with uint16 char codes. Decoded at load time by the `strDec` runtime function. When rolling cipher is on, the encoding key is derived implicitly from bytecode metadata (no plaintext seed). Strings remain encoded even after outer encryption is reversed.
122
-
-**Per-build identifier randomization**: All internal VM identifiers (`_vm`, `_BT`, `stack`, etc.) are replaced with random 2-6 char names generated via LCG PRNG (same seed as opcode shuffle). Adaptive retry increases minimum length after collisions. Managed by `RuntimeNames` interface in `encoding/names.ts`.
133
+
-**Unified naming system** (`naming/`): A central `NameRegistry` + `NameScope` + `NameToken` architecture manages all per-build randomized identifiers. The registry creates scoped name pools, resolves all names collision-free via `resolveAll()`, and produces the encoding alphabet. The `setupRegistry()` function bridges the registry to the existing `RuntimeNames`/`TempNames` interfaces for backward compatibility. AST nodes accept `Name` (NameToken | string) for all identifier positions. Handler locals use `ctx.local("descriptiveName")` pattern (currently pass-through, will be registry-backed). Post-processing `obfuscateLocals` still renames handler-local variables.
134
+
-**Per-build identifier randomization**: All internal VM identifiers are replaced with random 2-5 char names via the NameRegistry's LCG PRNG (same seed as opcode shuffle). Three length tiers: short (2-3), medium (3-4), long (4-5). Adaptive retry increases length after collisions. The encoding alphabet (64-char, Fisher-Yates shuffled) is also generated by the registry.
123
135
-**Watermark**: Steganographic — the WATERMARK_MAGIC constant (FNV-1a of "ruam" = `0x2812af9a`) is XOR-folded into the FNV offset basis used for key anchor computation. No visible variable, string, or pattern in output. Verified by comparing key anchor results: using standard FNV basis instead of watermarked basis breaks all rolling cipher decryption.
124
136
-**Prototypal scope chain**: Scope chain uses `Object.create(parent)` / `Object.getPrototypeOf(scope)` instead of a `{sPar, sVars}` linked list. Variables are own properties on scope objects. `in` operator traverses the prototype chain for reads; `Object.prototype.hasOwnProperty.call` walk for stores. TDZ uses a per-build sentinel object at IIFE scope (identity comparison via `===`). Program scope is `Object.create(null)` with `defineProperty` bindings.
125
137
-**Array-based stack**: Stack uses native `Array.push()`/`Array.pop()`/`S[S.length-1]` instead of a dedicated stack pointer variable (`S[++P]`/`S[P--]`/`S[P]`). The stack pointer (`stp`) is generated but unused (preserved for LCG sequence stability). Exception handlers save `S.length` as `_sp` and restore via `S.length=_h._sp`. Stack encoding Proxy intercepts `push()` set traps on numeric indices.
0 commit comments