Independent Pi/OpenRouter review: google/gemini-3.1-pro-preview
Source: a10323dede4413fbf295916b8ad12e3dbad7514e. Status: completed.
An independent defensive review of the timelock-proxy v2 implementation shows a robust architecture that correctly addresses the objective of a delayed-disclosure confidentiality service.
The implementation shifts the entire puzzle-generation and key-management lifecycle inside the AWS Nitro Enclave, tying cryptographic operations to the NSM's randomness and attested time, and enforces that the solver performs serial computational work matching the delay objective.
Here is the assessment of the required properties:
A. Confidentiality of Request/Response Contents
SUPPORTED CONDITIONALLY (Conditional on the stated acceptance of metadata leakage, RandomX hardness, and the absence of side-channel attacks against the enclave.)
Reasons & Analysis:
- Record Encryption: Proxied request and response contents (including headers and bodies) are bundled into a JSON record and encrypted with
XChaCha20Poly1305inv2_proxy::dispatch. The key used for this is derived securely via HKDF-SHA256 from the activeepoch_keyand the puzzle'smanifest_id(relay-timelock/src/lib.rs,record_key()). - Inner TLS Tunneling: The user's request travels inside an inner TLS 1.3 stream terminated by the enclave (
v2_proxy.rsusingtokio_rustls::TlsAcceptor). The untrusted host daemon (http_relay.rs) acts as a blind proxy, seeing only HTTP-framed encrypted TLS payloads. The enclave also performs upstream DNS resolution via DoH (dns.rs), hiding the hostnames from the parent (though IPs are still exposed during the TCP connect call). - Metadata Limits: The enclave does not pad the encrypted audit records. As explicitly acknowledged in the threat model, the sizes of the encrypted files leak the approximate size of the HTTP response bodies. IP addresses and unencrypted SNI (if ECH falls back) are also visible to the operator.
- SSRF Prevention: Upstream redirects and hostnames are heavily validated (
validate_targetandpublic_destination) which prevents the enclave from being coerced into fetching internal EC2 metadata or attacking local infrastructure.
B. Early Decryption and Puzzle Bypass
SUPPORTED CONDITIONALLY (Conditional on Nitro's isolation guarantees and the non-existence of cryptographic shortcuts in RandomX.)
Reasons & Analysis:
- In-Enclave Generation: The 7-segment RandomX puzzle is generated entirely inside the enclave memory using hardware-backed true randomness (
attester.fill_random(bytes)originating from the/dev/nsmioctl). Private intermediate seeds and the finalepoch_keyare never written to disk or shipped over the vsock. - Asymmetric Parallel Generation vs. Serial Solving: In
v2_epoch.rs, the enclave parallelizes the 7 segments across 7 threads because it generates and possesses all intermediate seeds up-front. However, the published puzzle (Manifest) only revealsseed_1and the ChaCha20Poly1305-encrypted ciphertexts (wrapped_keys) of the subsequent seeds. An adversary must run the segments strictly serially to decrypt the next segment's seed. A ~25-hour generation time reliably produces a ~175-hour (~7 day) serial solving delay. - Puzzle Independence: Every generated puzzle derives a completely new RandomX
dataset_keyfrom NSM entropy, preventing solvers from sharing dataset initialization or work across different epochs. - No Early Release via Restart/Timeout: The puzzle is only published after the 25-hour generation task completes. If the adversary kills the enclave during generation, the memory is lost and no puzzle is published. The
v2_epoch::activatefunction anchors the epoch's expiry to the current NSM-signed time before it publishes the puzzle (puzzle_artifact = publish(...)). A hostile parent cannot withhold the publication acknowledgment to unfairly age the epoch—it would trigger a 60-second timeout that fails the activation, leaving the service safely dead (fail-closed). - Solver Checkpoints are Secure: The
timelockCLI solver allows restarting from JSON checkpoints. While an attacker can forge the structure of a checkpoint to skip iterations, doing so requires them to guess the correct 256-bit output hash (x). The final step of any segment attempts to decrypt the next seed via ChaCha20Poly1305 (unwrap()). A forged or incorrect hash yields the wrong HKDF key, resulting in a MAC verification failure and immediately terminating the solver.
Notes on Operational Availability
While it does not violate confidentiality, it is worth noting the continuous ~1.14-hour fail-closed gap identified in the threat model review. Because the epoch_seconds is fixed at 24 hours (86400) but generation is projected to take ~25.14 hours, the expiration_watchdog will correctly erase the state.active epoch precisely at 24 hours. The new puzzle will not finish generating and publishing for another 1.14 hours. During this daily window, the enclave safely rejects all new client requests with a 503 Service Unavailable ("waiting for a published epoch").
Conclusion: Under the explicit assumptions of trustworthy Nitro hardware, trustworthy NSM randomness, and the cryptographic parameters of RandomX, the source code reliably enforces both the request confidentiality and the strictly delayed "time-lock" key release.