Skip to content

feature: randomize constants xorshift triple (#69) - #107

Merged
mcpolo99 merged 1 commit into
developfrom
69-constants-xorshift
Sep 21, 2026
Merged

mcpolo99 merged 1 commit into
developfrom
69-constants-xorshift

Conversation

@mcpolo99

Copy link
Copy Markdown
Owner

Level 2 constant randomization — Constants xorshift (#69)

Removes the fixed 12/25/27 xorshift shifts from the Constants protection key generator. The generator n ^= n >> a; n ^= n << b; n ^= n >> c runs identically on the obfuscator (EncodePhase) and the injected runtime (Constant.Initialize) to expand a seed into the 16-word key stream; the fixed shifts let de4dot/AV pattern-match the stub.

Change

  • The triple is chosen per module from a curated set (ConstantXorshift.Triples) and injected into the runtime Initialize via Mutation.KeyI2/KeyI3/KeyI4.
  • Both sides share the triple, so the round-trip holds for any shifts.

Curated set (scripts/curate_xorshift.py)

Each triple is a full-period xorshift (period 2³²−1), verified exactly by computing the GF(2) transition matrix's multiplicative order (primitivity test against the factors of 2³²−1 = 3·5·17·257·65537), restricted to non-extreme shifts (2–30) for good avalanche over the 16-word expansion. 128 triples → ~7 bits of per-module identity.

Notably, the historic 12/25/27 is not even full-period — the curated set is a strict quality upgrade.

Fail-loud injection

Injection now goes through a new MutationHelper.InjectKeysEnsured, which verifies every requested placeholder is present in the method before injecting and throws otherwise. A future runtime-source change that drops a placeholder fails the build instead of silently desyncing encode/decode. (The compressor's local verifier from #106 can later migrate to this shared helper.)

Validation

  • Builds clean (Core + Runtime + Protections).
  • 270_EnumArrayConstantProtection.Test and 193_ConstantsInlining.Test pass — both obfuscate and run, exercising the full encode → InjectKeys → runtime Initialize key path; a broken sync fails immediately.
  • Curation script reproducible across runs.

Remaining on #69 (follow-ups)

Part of #69. Related: #106 (compressor moduli).

The Constants protection expands its key with a 32-bit xorshift
(n ^= n >> a; n ^= n << b; n ^= n >> c) on both the obfuscator
(EncodePhase) and the injected runtime (Constant.Initialize), using the
fixed 12/25/27 that de4dot/AV pattern-match to fingerprint the stub.

The triple is now chosen per module from a curated set and injected into
the runtime Initialize via mutation keys (KeyI2/KeyI3/KeyI4). Both sides
share it, so the round-trip holds for any shifts; the curated triples are
additionally full-period (period 2^32-1, verified by GF(2) matrix order)
with non-extreme shifts, so the key stream is well mixed. The historic
12/25/27 is not even full period. ~7 bits of added per-module identity.

Injection goes through a new MutationHelper.InjectKeysEnsured that
verifies each placeholder is present, so a runtime-source change that
drops one fails the build instead of silently desyncing.

scripts/curate_xorshift.py regenerates the set deterministically.
Validated by 270_EnumArrayConstantProtection.Test and
193_ConstantsInlining.Test.
@mcpolo99
mcpolo99 merged commit b6e07a4 into develop Sep 21, 2026
3 checks passed
@mcpolo99
mcpolo99 deleted the 69-constants-xorshift branch September 29, 2026 19:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant