Build1 publisher2 min readPublished
Client-side XOR hardening costs three byte-exact implementations of one derivation
A developer XOR-encodes his app's config values with working keys derived from a 32-byte master key that ships inside the binary, then hands the build to a frontier model to go looking for it. The published account stops before the result.
The Engineer · Build desk
What happened
- The developer wrote the limit into his own threat model: the master key ships inside the binary, because the application has to decode its values, and a capable reverse engineer could find it and reproduce the decoding.
- Configuration values are XOR-encoded, each with a working key derived at runtime from one 32-byte master key, and the working keys are never stored at rest in the binary.
- The derivation deliberately strips shared prefixes so that related secrets come out looking unalike in the shipped artifact.
- The same derivation exists in three independent places, the application runtime, a build-time tool and a native build script, written in three different languages that must agree byte for byte.
- He then gave a frontier LLM the build and had it investigate whether it could work backward from the shipped artifact to the secrets the application recovers for itself.
Compiled by The EngineerSomething wrong?How this is made
Why it matters
- cost The maintenance cost falls on whoever owns all three toolchains: a single byte of disagreement between the implementations leaves the shipped application unable to decode its own configuration.
- constraint This design cannot promise secrecy, so what a buyer gets is the hours it costs an attacker, and the author states the ceiling himself: obfuscation can only raise the cost of recovery.
- decision An author who knows which data matters and where decoding happens cannot grade his own artifact's opacity, so measuring it requires handing the build to an investigator who lacks that context.
- precedent The procedure is symmetric: anyone holding the compiled app can pull it apart on their own device and run the same blind investigation the author ran on his build.
XOR reverses the moment the matching key bytes are in hand, so the algorithm is the easy part. The difficulty the author aimed for is discovery: recognising which numeric arrays hold encoded values, finding the master key, and connecting it to the derivation and the decoding logic [5]. Every working key comes from one 32-byte secret, so 256 bits of material inside the artifact stand behind all of it [18]. In the shipped build those encoded values appear as numeric byte-array literals resembling hashes, and no string reads as a key [6].
The prefix stripping is aimed at a step that comes before any decoding. An investigator can cluster values that look alike, infer that the group shares a purpose, and then go looking for the code that consumes it. Stripping shared prefixes takes away that first sorting step, and the application can still recover each value [8].
The developer is clear about which half of the experiment is hard to read. "The interesting part of the experiment became the investigation around the model: how to challenge its interpretations, what evidence to demand, and how much confidence to place in a failed recovery attempt," he wrote [13]. A successful recovery would settle the question outright; a failure bounds one attempt by one investigator. The supplied account breaks off inside the sentence that introduces the investigation setup, and it does not report whether the model found the master key [16].
The maintenance side is fully documented. A change to the derivation means three edits, in three languages, that have to produce identical bytes [17]. Conceptual agreement between the three implementations is not enough, because differences in how languages handle bytes and numeric operations matter when the output of one implementation becomes the input to another [10].
For the negative half of this experiment to transfer to another build, the model you are worried about would have to be at most as strong as the one used here, and its operator would have to stop after a single investigation. The attacker would also have to come in knowing only what a blind investigator knows. The author sets the same boundary from the other direction: he treated this as an obfuscation test, and says calling it cryptographic protection would obscure the engineering question he could actually investigate [14].
What to watch
- Whether the author publishes the model's transcript, including the prompts and the point at which the recovery attempt stalled or succeeded.
- Whether anyone without access to the source or the design notes repeats the blind investigation on the same shipped build.
- Whether the three implementations adopt a shared test vector, so a divergent derivation fails the build instead of the running application.