feat(native): R2-R3 decode + N1-N5 native sensor synthesis (ADR-0024) - #13
Merged
Conversation
Static-decode every gB("…") / gC(N) / gF(N) call in the eT15wiaE
init.js by reimplementing the base-91-ish decoder in Node + Babel
(px-research/tools/decoder/). 1 457 string literals inlined across
two passes, surfacing the sensor builder (`yA` → `vP` → `jw` → `hP`
→ `vQ`) and the px-cloud cookie/path constants.
R3 finding: the px-3 payload encryption is XOR(0x32) + base64 +
a string-splice VM (`vQ`). No AES, no HMAC at the payload tier;
integrity is the separate `pxhc` MD5 cookie. Notes captured in
`px-research/notes/eT15wiaE/r{2,3}-*.md`.
ADR-0024 promotes ADR-0010 (deferred native synthesis) to a 5-sprint
plan: extract `vN`, port cipher core, build event collector,
wire `NativeSolver`, generalise per-tenant. ADR-0010 marked
Superseded by ADR-0024.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Add the dispatch-table-free pseudocode for vN(target, lenBound, secret) so the N1 sprint (ADR-0024) starts from algorithmic notes rather than a switch/with/case trace. Also note vL = jw(base64(pf()||fallback), 10) and the XOR-key pair iS=50 (payload) / vJ=10 (secret feed). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Port the eT15wiaE px-3 sensor cipher primitives from the captured init.js to Rust under `px-native/src/cipher/`: - xor.rs: `jw(buf, key)` single-byte XOR (IS=50 payload, VJ=10 secret) - b64.rs: `h_p(buf)` standard base64 (alphabet `hI` line 583) - remap.rs: `v_m(t,n,e,r,g)` linear remap, Math.floor-rounded - secret.rs: `v_l(pf)` = jw(b64(pf), VJ) - offsets.rs: `v_n(target_len, len_bound, secret)` offsets PRNG - splice.rs: `v_q(salt, payload, offsets)` interleaves salt into payload Each module is dependency-free (no `base64`/`hex` crates). All files under the 200-LOC rule. Round-trip tests vs a JS reference (`px-research/tools/decoder/`): 6 fixture-driven tests + 11 unit tests pass. Cipher matches the JS source byte-for-byte across ASCII inputs. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
N2 — cipher/sensor.rs: encrypt_sensor(events_json, pf, cu) chains
jw → h_p → v_n → v_q matching the JS `vP` reference. Fixture
round-trip for vP added (3 vectors).
N3 — events/: SensorEvent + EventField data model, SyntheticIdentity
mirror of the camoufox synthetic-user pool, default_batch builder
emitting PX561/PX11978/PX12457 with realistic shapes.
N4 — infrastructure/sensor_solver.rs: SensorNativeSolver impls
NativeSolver. Builds payload via N2+N3, POSTs to
${origin}/${app_id_tag}${sensor_path}, parses Set-Cookie into
PxCookieBundle. cookies.rs is a small parser for the subset
PX servers emit.
N5 — profile/: TenantProfile TOML schema (app_id, app_id_tag,
sensor_path, pf_fallback, xor_keys). Profile bundled at
px-native/profiles/eT15wiaE.toml.
Also fixed v_q to honour JS String.prototype.substring semantics
(clamp to [0, len], swap if start > end) so the encoder handles
small payloads/long secrets without erroring.
Tests: 30 in px-native (lib + cipher_fixtures + end_to_end);
121 workspace-wide. clippy --workspace --all-features clean under
the unwrap/expect/panic ban.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces PR #12 (closed when the base research branch was merged + deleted). Stacks four logically-cohesive commits on top of the now-landed
research/r0-r2-pedidosya-eT15wiaE-2026-05-19.R2 — pass-2 deobfuscation
gB(t)base-91 decoder + Babel transform (px-research/tools/decoder/).yA → vP → jw → hP → vQ.R3 — sensor RE
vQ). No AES, no HMAC at the payload tier.vNun-flattened to pseudocode for direct Rust port.ADR-0024
N1 — cipher core
px-native/src/cipher/(xor/b64/remap/secret/offsets/splice/sensor + mod).cipher_ref.js) + fixture emitter + Rust round-trip tests.N2 —
encrypt_sensorwrappervP-equivalent entry point.v_qto honour JSString.prototype.substringsemantics (clamp + swap).N3 — event collector
events/module:SensorEvent,EventField,SyntheticIdentity,default_batch.N4 —
SensorNativeSolverinfrastructure/sensor_solver.rsimplsNativeSolver::solve.${origin}/${app_id_tag}${sensor_path}, parsesSet-CookieintoPxCookieBundle.N5 — TOML tenant profile
profile/schema.rs+px-native/profiles/eT15wiaE.toml.Test plan
cargo clippy --workspace --all-targets --all-features -- -D warnings -D clippy::unwrap_used -D clippy::expect_used -D clippy::panic …cleansensor_solver.rs147)🤖 Generated with Claude Code