reviews/current/OBJECTIVE-REVIEW.md
On this page

Independent model reviews of the confidentiality objective

Date: 2026-09-09. Runtime source: a10323dede4413fbf295916b8ad12e3dbad7514e.

Status: all nine requested models have completed an assessment. All attempts in this panel have finished; incomplete attempts are retained separately. No runtime code was changed for this review.

Question and current assessment

The requested objective is a GET-carried proxy (upstream GET is acceptable for now) whose request and response contents remain confidential from the operator and other intermediaries until approximately one week of public RandomX work. AWS is trusted; the account owner is not. RandomX is assumed to resist shortcuts to the specified dependent computation. Its composition, native integration, secret handling, lifecycle and verification remain review targets.

Most completed reviews support the narrower cryptographic objective conditionally; Gemini and DeepSeek dispute it, with claims assessed below. No concrete path to an epoch key, later seed, terminal output or otherwise hidden plaintext has been identified in the reviewed v2 path. This does not establish that no such path exists. It does not establish seven days of wall-clock secrecy, immunity to content inference, or security against a plaintext recipient voluntarily sharing an exchange.

One native implementation bug was confirmed: seven concurrent RandomX VM creations race on the global AES probe variable. ThreadSanitizer reproduced it. No key disclosure or early-solving impact was demonstrated. It remains unfixed in the reviewed production revision; see finding 5.

Requested panel

The user's corrected shortlist contains nine models: eight through Pi/OpenRouter and GPT-5.6 Sol through Codex. Only these models form this panel. Raw assessments are retained even where the consolidation rejects a claim.

Model and report Completion Model's assessment of content / early-key protection
Muse Spark 1.3 Complete Conditional / conditional
Grok 4.6 Complete Conditional / conditional; no wall-clock theorem
GLM-5.3 Complete Conditional / conditional; some supporting claims corrected below
Kimi K3 Complete on retry Conditional / conditional; native-code coverage explicitly incomplete
GPT-5.6 Sol via Codex Complete Conditional for non-recipient adversaries; literal recipient-collusion objective violated; no concrete early-key shortcut
GLM-5.3 Flash Complete Conditional / conditional; some supporting claims corrected below
Gemini 3.8 Flash Complete after internal retry Claims A/B violated; metadata and epoch-relative limits valid, claimed header/plaintext and stale-puzzle bypasses not substantiated
Qwen 3.8 Max 0902 Complete on retry Conditional / conditional; some supporting claims corrected below
DeepSeek V4 Pro 0813 Complete with extended reasoning disabled Rejects objective; solver-speed limit valid, claimed diagnostic leak and transport failure not substantiated

The selection record identifies the exact provider IDs, excluded models from the initial broader batch, and retry directories. Extra outputs already produced before the correction are retained for an honest execution record and excluded from the panel conclusions.

Grounded findings and limits

1. Known content can be inferred from public ciphertext length

Confirmed locally; confidentiality limitation, not key recovery. The enclave serializes the audit record without padding and encrypts it with XChaCha20-Poly1305. The public envelope exposes its ciphertext as hexadecimal (v2_proxy.rs, lines 98–107; timelock/lib.rs, lines 92–123). Ciphertext length is plaintext length plus a 16-byte tag. Known candidates with different lengths can therefore be distinguished before solving.

The local reproducer used the real dev host and enclave binaries, the same request URL and a local authenticated TLS fixture. Four requests alternated between known 32-byte and 1,024-byte response bodies. Their public ciphertext lengths were respectively 466 and 1,795 bytes on both repetitions. No solver or decryptor was invoked. Recorded evidence. This uses synthetic data and does not test Nitro isolation. Other unknown record fields can complicate inference in real workloads; the example establishes a counterexample to a universal claim that contents cannot be inferred.

Direct v2 networking also exposes destination IPs to the parent, DNS questions to the resolver, and often SNI to the parent. Automatically following an HTTPS redirect can promote response content into hostname metadata: for example, Location: https://SECRET.leak.example/. The code follows that hostname through DNS and TLS (v2_proxy.rs, lines 163–195; net.rs, lines 94–153). This redirect observation was checked statically; no production redirect experiment was run.

2. A colluding intended recipient can disclose the exchange immediately

Objective boundary, not an implementation bypass. The intended destination receives the GET URL and knows the response it sends. If it colludes with the operator, it can simply provide both. Trusting AWS and assuming a strong RandomX primitive cannot prevent a plaintext recipient from redistributing plaintext. The original threat model's unrestricted collusion wording did not make this boundary sufficiently explicit. The threat model now states it, alongside the content-inference limit. These documentation changes do not repair or strengthen runtime confidentiality; they describe its scope more accurately.

Malicious destinations still matter as potential attackers of enclave parsers, TLS, redirect handling and other users' secrets. This boundary does not declare their inputs safe or exclude implementation bugs.

There are also explicit trust conditions beyond AWS: the client's verifier and independently obtained measurement pin, ordinary cryptography, and upstream WebPKI authentication. In particular, net.rs builds its upstream TLS roots from webpki_roots::TLS_SERVER_ROOTS. A malicious trusted CA able to issue an accepted certificate for the target, colluding with the parent that routes its traffic, can impersonate that target and receive the request immediately. That does not require breaking AWS or RandomX. The supplied threat model already assumes correct WebPKI authentication; this review cannot establish the stronger literal claim that trusting AWS alone is sufficient. No CA-compromise experiment was performed; this follows from the configured upstream authentication boundary.

3. RandomX strength does not establish a seven-day wall-clock lower bound

Known design limit and missing timing evidence. Generation evaluates seven secret-seeded chains in parallel. The public puzzle releases only the first seed; each terminal output unlocks the next seed and the seventh unlocks the epoch key. That provides a serial dependency under the cryptographic assumptions (timelock/lib.rs, lines 301–397, 438–497).

It does not prevent faster hardware or implementation improvements from performing the required work sooner. Sharing completed work means every adversary benefits from the fastest successful solver. The hardware gate constrains enclave generation; it does not constrain external solver speed. The 43,768,124-iteration setting is calibrated, not a proven timing bound.

The delay begins when the parent first receives the puzzle, not independently for each request. With a 24-hour serving epoch and a solver taking seven days, late requests have about six days remaining. Full-duration production generation, rollover and recovery were not observed as part of this review.

4. The checked lifecycle blocks several obvious early-key strategies

Supporting evidence, not an impossibility proof. Production uses direct, fallible NSM entropy for the epoch key and private puzzle material. The v2 generation path does not accept host-supplied puzzles, seeds or checkpoints. Later seeds and terminal outputs have no identified export path. Chosen valid client requests yield AEAD ciphertext, which is not a key-recovery oracle under the assumed cryptography.

Activation anchors trusted NSM time and monotonic time before the first puzzle write. Delaying a persistence acknowledgement consumes the epoch's lifetime; it cannot start a fresh lifetime for an already disclosed puzzle. Future puzzle generation overlaps the current epoch, but future publication waits for its trusted deadline. Admissions require both clocks to be valid; the expiration watchdog and bounded admitted-request lifetimes limit key retention (v2_epoch.rs, lines 21–35, 76–150).

The live client verifies the AWS signature, exact independently selected PCR0, fresh nonce/time and attested SPKI against the actual inner TLS peer before sending the destination. Altering outer GET transport operations cannot forge valid records inside an established inner TLS connection (client.py, lines 143–180; verify.py, lines 52–142).

5. Confirmed native data race; other native safety remains insufficiently reviewed

Confirmed bug, no demonstrated confidentiality impact. Sol's independent native supplement found a shared non-atomic aesDummy in VmBase::allocate (virtual_machine.cpp, lines 98–116). Every hardware-AES VM loads and writes it as an instruction probe. The application creates seven VMs in concurrent workers. volatile does not make these accesses atomic or synchronized; the C++ execution has a data race.

The reproducer, linked against an otherwise unchanged ThreadSanitizer-instrumented native library, reported concurrent writes to global randomx::aesDummy from VmBase::allocate through randomx_create_vm. Full captured evidence. It uses local AArch64 light/interpreted hard-AES VMs, whose allocation probe is the same as production full/JIT VMs. It does not run the production enclave or show a key/plaintext leak. Symbolizer startup warnings occurred, but the sanitizer identified the function and global by name.

The probe operates on non-secret dummy data before the first hash. The confirmed consequence is undefined native behavior; no concrete crash or confidentiality exploit was established. Serialize VM creation in the wrapper, or synchronize the native probe with std::call_once, then repeat the sanitizer check and native correctness tests before accepting a new measured build. No such fix has been applied to runtime code during this review.

A second harness run serialized only randomx_create_vm calls with a mutex; the same instrumented library then exited successfully without a sanitizer race report. Mitigation-check evidence. This validates a narrow proposed mitigation in the harness; it is not a deployed fix or proof that the native library has no other races.

Reproduce from the repository root using a fresh build directory:

cmake -S vendor/randomx -B .local/randomx-tsan-review -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_C_FLAGS='-fsanitize=thread -fno-omit-frame-pointer' -DCMAKE_CXX_FLAGS='-fsanitize=thread -fno-omit-frame-pointer' -DCMAKE_EXE_LINKER_FLAGS=-fsanitize=thread -DCMAKE_POLICY_VERSION_MINIMUM=3.5
cmake --build .local/randomx-tsan-review --target randomx -j 4
clang++ -std=c++17 -g -O1 -fsanitize=thread -fno-omit-frame-pointer -pthread -I vendor/randomx/src reviews/check-randomx-vm-race.cpp .local/randomx-tsan-review/librandomx.a -o .local/randomx-tsan-review/check-vm-race
TSAN_OPTIONS=halt_on_error=1 .local/randomx-tsan-review/check-vm-race
TSAN_OPTIONS=halt_on_error=1 .local/randomx-tsan-review/check-vm-race --serialize

The first run is expected to fail with a data-race report. The second checks the proposed serialization in the harness. A machine without hardware AES exits 77 as a skip; that is not a successful race check.

App-owned key buffers and canonical plaintext use zeroizing owners, but ordinary JSON values, response and TLS buffers, compiler/library copies and native RandomX VM memory are not comprehensively erased. No reachable extraction path for the untrusted parent was demonstrated under trusted Nitro isolation. The absence of a demonstrated path is not evidence that all native memory-safety or microarchitectural attacks have been excluded.

The Pi snapshots include the Rust FFI and native header, not the entire RandomX C++ tree, dependency implementations or kernel. Sol and the consolidating agent followed relevant native allocation/VM/flag code locally. A native full-mode v2 known-answer test passed, but this is not a full native-code security audit. Reproducible measurements establish source-to-image evidence under the stated build trust; they do not establish source safety.

6. Storage and later provenance have separate gaps

A parent's OK\n persistence acknowledgement does not prove durable or public storage. The parent can withhold puzzle publication after receiving it; that does not move the enclave's first-disclosure time anchor, but gives the parent a lead over solvers that only see later public publication. Archived evidence does not independently attest the first public availability time.

The current S3 uploader lacks delete permission, but Object Lock is disabled. Individual record envelopes are not service-signed; after the epoch key becomes public, anyone can create a valid new AEAD envelope. Historical origin therefore requires a prior trusted ciphertext digest/receipt or publication record. These are retention/provenance limits, not early key-recovery findings.

Corrections to model claims

These corrections matter because a model's confidence is not a substitute for checking its premises. Original reports are preserved unchanged.

Validation performed during consolidation

Check Result and scope
cargo test -p relay-timelock --lib 3 passed; one full-memory test initially ignored. Native v2 light vector, entropy failure, and round-trip/checkpoint/tampering coverage.
Explicit randomx::tests::full_mode_upstream_v2_vector -- --ignored --exact 1 passed, 28.58 seconds; local full-memory native v2 vector. This is not a production-duration run.
Python test_verify.py plus test_delayed_publication_ack_never_rebases_expired_puzzle_as_fresh_epoch 18 passed, 7.25 seconds in the installed client test environment; signature/nonce/SPKI/policy rejection and real dev-host/enclave delayed-ACK rejection.
Response-length reproducer Passed; known responses distinguished without key recovery or solving.
Native concurrency reproducer ThreadSanitizer confirmed a data race on randomx::aesDummy; this is a failing native-safety check, not a successful security check.
Same harness with --serialize Passed without a sanitizer race report when VM creation was protected by a mutex; no production fix applied.
Large TLS-flight check Passed using the real Python client and dev Rust host/enclave; expected response after three transport chunks.
Sol's separate Rust execution Reported 6 timelock and 24 enclave tests passed; its initial full-memory vector was ignored. These overlap some consolidation checks and are not added as independent evidence counts.

No production traffic was generated, production configuration was not changed, and no enclave restart was performed for these reviews. None of these checks is a proof of security or a substitute for an independent native-code audit.

Method and reproducibility

Runner. Each Pi model received the same line-numbered 542,023-byte snapshot, SHA-256 07ec105a70b1dfb77254f4fbf6ecbe439bddf6fac6fdaa1cff8dcbe6b2ae532e. Runtime was frozen at a10323d; documentation and CI were separately labelled at 85c61e96590b52ded80a995ef5d1e379b2287761 and are claims to evaluate, not measured runtime. The manifest records file hashes, prompts, model IDs and focus variants. No reviewer was given another model's report.

Pi had no tools, extensions, local context files or skills, and could not run tests. Credentials were kept out of prompts and argv. Provider calls used each requested model's exact catalog identifier. Sol used Codex and independently read the local repository and ran checks. This is independent prompting, not a claim of statistically independent model training or independent human audits.

The initial 32,768-token allowance was exhausted by four selected models before a complete final assessment. Those attempts remain marked incomplete. Retries use 65,536 output tokens; Qwen's retry uses medium reasoning, while the other three use high. Gemini's 65,536-token attempt failed with upstream idle timeouts; its next attempt uses a 32,768 total output allowance with an explicit 8,192-token reasoning budget, which was not reflected in usage (31,455 reasoning tokens reported before truncation). A subsequent medium/65,536 attempt recovered from an internal provider timeout and produced a complete 4,335-token final response with stopReason=stop. The initial runner classified any earlier error as fatal; that classification was corrected with an explicit audit record in its result JSON. The negative review was retained and evaluated, not retried for agreement. DeepSeek's high/65,536 attempt used the entire allowance for reasoning without a final response; the medium-effort retry also exhausted 65,536 output tokens (64,413 reasoning tokens), leaving only a truncated final assessment. It is retained as incomplete. Its surviving opening gives conditional support to the core confidentiality and early-key properties, unlike the completed direct-answer attempt. This disagreement between attempts is preserved; the partial answer is not counted as another completed review. A separate direct-answer attempt, with extended reasoning disabled and a 32,768-token allowance, completed with a 7,328-token final assessment against the identical snapshot. Its lower reasoning setting and numerous unsupported assertions limit its evidentiary weight. Both attempts are retained; they are one requested model, not additional independent panel members. Each attempt has its own manifest, usage, elapsed time, stop reason and final text. Truncated or failed answers are not counted as complete.