reviews/current/objective-20260909T223027Z/moonshotai__kimi-k2.7-code.md
On this page

Independent Pi/OpenRouter review: moonshotai/kimi-k2.7-code

Source: a10323dede4413fbf295916b8ad12e3dbad7514e. Status: completed.

Independent assessment

Scope: frozen source commit a10323dede4413fbf295916b8ad12e3dbad7514e, enclave binary attested-relay-enclave (v2_main.rs reachability), with documentation at 85c61e96590b52ded80a995ef5d1e379b2287761 treated as a claim. Tests and CI attestations were not executed and are not treated as proof.


High-level verdicts

Property Verdict
A. Confidentiality of request/response contents from intermediaries/operator before the intended ~1-week delay SUPPORTED CONDITIONALLY – the cryptographic composition blocks direct plaintext disclosure if the RandomX primitive, Nitro isolation, NSM time, and the client verification path hold. Metadata (sizes, timing, SNI when ECH fails, status codes, artifact names) is visible; memory/side-channel hygiene is not proved.
B. Early recovery of epoch keys/private seeds/intermediates or equivalent decryption capability without breaking RandomX SUPPORTED CONDITIONALLY / NO DEMONSTRATED VIOLATION – I found no code path that releases an epoch key, an unreleased seed, or a usable shortcut before the intended serial work. The main caveats are (1) the next epoch key already exists in enclave memory during the current epoch, (2) no evidence is provided that RandomX cache/VM memory is securely scrubbed, and (3) no per-record signatures exist, so post-release provenance is weak but that does not enable pre-release decryption.

The design does not provide per-request delay: the lock time starts at puzzle publication, so records created late in an epoch have less remaining delay than records created early. This is acknowledged in the threat model (threatmodel.md) and is not treated as a confidentiality violation, but it is a real limitation on the advertised “approximately one week” property.


A. Confidentiality of request/response contents

What blocks content recovery

  1. Records are encrypted under the hidden epoch key before leaving the enclave.

    • crates/timelock/src/lib.rs:81-90 derives record_key from epoch_key via HKDF-SHA256 keyed by the manifest id.
    • crates/timelock/src/lib.rs:92-124 encrypts with XChaCha20Poly1305 using a 24-byte random nonce and an AAD that binds version || epoch || sequence || manifest_id.
    • crates/enclave/src/v2_proxy.rs:104-107 waits for the sealed JSON to be published before returning the upstream response.
    • The only thing published is the ciphertext hex string (EncryptedRecord), plus a SHA256-named artifact file on the untrusted host.
  2. The epoch key is not in any public artifact.

    • The published manifest (crates/timelock/src/lib.rs:28-41) contains only key_commitment = SHA256(epoch_key), plus the public wrapped keys and seed_1.
    • solve() in crates/timelock/src/lib.rs:458-498 recomputes the chain and checks the commitment; only the correct epoch_key passes.
    • Attestation policy (crates/enclave/src/v2_main.rs:55-71) advertises the service signing key and work parameters, but never the epoch key or seeds.
  3. The enclave does not serve application traffic until a fresh attestation binds the exact code, hardware policy, and inner-TLS peer.

    • crates/enclave/src/v2_main.rs:94-114 requires a 32-byte nonce and includes the enclave TLS SPKI in the NSM document.
    • python/attested-relay/src/attested_relay/verify.py:131-146 checks the nonce, timestamp freshness, PCR0, Graviton5 readiness, and public_key == peer SPKI.
    • python/attested-relay/src/attested_relay/client.py:143-165 performs this verification before any request is sent and refuses dev mode unless explicitly allowed on loopback.
  4. Upstream destinations are resolved and validated inside the enclave.

    • crates/enclave/src/dns.rs resolves over DoH by IP; the parent sees only encrypted DNS traffic.
    • crates/enclave/src/v2_proxy.rs:127-137 and crates/enclave/src/net.rs:240-251 reject private/loopback IPs, non-443 ports, credentials, fragments, and redirects to disallowed hosts.
    • WireGuard mode (crates/enclave/src/wg.rs) hides upstream IPs from the parent entirely.

Concrete execution trace for A

Attacker: parent host / network observer with access to all host-held artifacts and all bytes on the outer relay.

Limitations / what is not protected


B. Early epoch-key / seed / equivalent-decryption recovery

What I looked for

The review specifically examined: generation vs solving parallelism, shared work, publication ordering, host acknowledgements, time handling, restart, expiration, request leases, key reuse, checkpoints, attestations, and active/chosen-input attacks.

Findings supporting the no-early-recovery claim

  1. No shortcut in the wrapping chain.

    • Each segment is y = RandomX^{iterations}(seed_i), then seed_{i+1} (or epoch_key) is encrypted with a key derived from y (crates/timelock/src/lib.rs:246-284).
    • The published wrapped_keys reveal only ChaCha20-Poly1305 ciphertext; the wrapping key is HKDF-SHA256(y, context). Under the RandomX assumption, y cannot be predicted without doing the work.
  2. No cross-epoch or cross-segment shared work.

    • Fresh dataset_key, seven seeds, and epoch_key are drawn from NSM randomness for every epoch (crates/timelock/src/lib.rs:301-325).
    • The dataset is keyed by dataset_key, so each epoch requires fresh dataset setup (crates/timelock/src/randomx.rs:49-72).
    • seed_1 is public, but seed_2..7 are wrapped and never exposed until their segment is solved.
  3. Delayed/replayed host acknowledgements cannot extend or rebase an epoch.

    • crates/enclave/src/v2_epoch.rs:76-102 records activated_at_ms and expires_at_ms before waiting for the puzzle publication ACK. A late ACK cannot shift the wall-clock expiry.
    • If the ACK is delayed beyond expires_at_ms, active.accepts(now) fails and the epoch is discarded (crates/enclave/src/v2_epoch.rs:98).
    • The integration test tests/test_v2_e2e.py:345-361 demonstrates this: a 6-second ACK delay with a 5-second epoch leaves the service in warming and returns 503 without serving the request.
  4. Expired epochs reject new work strongly, and in-flight work keeps a bounded lease.

    • crates/enclave/src/v2_epoch.rs:40-52 watchdog erases the active state when monotonic_expired() is true.
    • crates/enclave/src/v2_proxy.rs:82-84 clones the current Arc<Epoch> before releasing the read lock; admitted requests keep the key alive until sealing finishes.
    • crates/enclave/src/v2_epoch.rs:153-211 tests that the key is dropped after the last request lease is gone.
  5. No host-provided epoch parameters or puzzles.

    • crates/enclave/src/v2_main.rs:160-168 verifies Graviton5 hardware, NSM PCR4 parent binding, and EC2 instance identity before production service starts.
    • crates/enclave/src/v2_epoch.rs:104-151 always generates the next puzzle inside the enclave using relay_timelock::generate_with_rng with NSM randomness; the parent cannot inject a manifest, seed, or epoch key.
    • On restart, v2_main.rs:169-172 and v2_epoch.rs:105 derive fresh signing material and a fresh random epoch counter; there is no persistence of old keys to reuse.
  6. Checkpoints cannot smuggle progress.

    • crates/timelock/src/lib.rs:434-455 validates manifest id, segment/iteration bounds, and a SHA256 checksum over the checkpoint fields.
    • crates/timelock/src/lib.rs:476-487 overwrites the resumed x only at segment boundaries via the authenticated AEAD unwrap; a wrong x simply fails with “segment authentication failed” in unwrap() (crates/timelock/src/lib.rs:262-284).
    • Unit tests in crates/timelock/src/lib.rs:638-661 verify tampered checkpoints are rejected.
  7. Attestations prevent relaying and replay.

    • The client supplies a 32_byte nonce; the NSM signs it (crates/enclave/src/attest.rs:136-168).
    • The NSM document binds the exact inner-TLS SPKI (crates/enclave/src/tls.rs:27-34, v2_main.rs:107), so relaying another enclave’s valid attestation to a different TLS endpoint is rejected by the Python verifier (verify.py:113-114).

What weakens the no-early-recovery claim

  1. The next epoch key is generated during the current epoch and remains in enclave memory until activation.

    • crates/enclave/src/v2_epoch.rs:104-151 computes generated = generate_with_rng(...) at the moment the current epoch becomes active, then waits (potentially another ~day) before publishing/activating it.
    • GeneratedPuzzle contains the full epoch_key (crates/timelock/src/lib.rs:49-52). This secret therefore lives inside the enclave for the entire lifetime of the previous epoch, not just its own.
    • Under the AWS trust model this is not accessible to the operator; however, it is a real increase in exposure window and a target for any side-channel or memory-extraction capability.
  2. No evidence that RandomX cache/VM memory is securely scrubbed.

    • crates/timelock/src/randomx.rs:39-118 wraps raw C pointers. Drop calls randomx_release_*, but RANDOMX_FLAG_SECURE (used at randomx.rs:59) only enforces W^X for JIT pages; it is not documented to zero scratchpad/dataset memory.
    • The Rust Zeroizing wrapper scrubs the high-level epoch_key and seeds on drop, but it does not reach the C++ allocator/VM state. After a VM is dropped and the allocator reuses the page, the internal chain values may remain physically present.
    • Mitigation: under AWS Nitro the enclave memory is not directly readable by the parent, but this remains an unverified assumption, exactly the kind the prompt flags as not assumed safe.
  3. No per-record provenance signature.

    • The record is secured only by AEAD (crates/timelock/src/lib.rs:92-124). Once the epoch key is public, anyone can construct a valid-looking record.
    • This does not allow an adversary to read records early, but it means the archive cannot prove that a record was produced by this enclave rather than forged after thefact. The threat model (threatmodel.md) already lists per-record origin signatures as a missing gap.
  4. Approximate delay is from puzzle publication, not from each request.

    • Daily epochs (config/relay-v2.toml:7) mean a request made just before the epoch expires is decryptable roughly one day sooner (on average) than a request made at epoch start.
    • This is explicitly accepted by the owner but is a real deviation from a uniform per-request delay.

Minimal reproduction/test sketches


Strongest reasons attacks are blocked


Missing evidence that limits the conclusion


Requested additional source

Please provide the complete **vendor/randomx/** C++ implementation (not just the header) for the pinned commit, so the memory-handling and flag behavior of the FFI layer can be reviewed. If a formal or experimental timing/noise analysis of the enclave’s RandomX usage exists, that would also reduce the conditional part of the verdicts.


Bottom line

I would not unconditionally rely on this for highly sensitive content, because the confidentiality guarantee is conditional on (a) the unproven RandomX serial-work assumption, (b) the unverified memory/side-channel behavior of the RandomX FFI and enclave runtime, and (c) the operational assumption that the service remains running long enough rotate epochs and publish puzzles. within the explicit assumptions stated by the owner—AWS and standard primitives are trusted, RandomX has no shortcut, and no side-channel extraction is available—the design appears to prevent in-scope adversaries from recovering request/response contents or epoch keys dramatically earlier than the intended serial solving delay. There is no code-backed violation of early key recovery, but the evidence is conditional, not comprehensive.