soft3/mudra/audit/signature-optimality/neptune-privacy.md

Neptune Privacy (XNT): matrix evidence, distinct from Neptune Cash

Date: 2026-09-12. Scope: released XNT L1/core/SDK, publicly linked mobile products, optional short addresses, and the boundary to advertised L2. Research and one synthetic local predicate/serialization check; no live transfers, restored accounts, whole-chain sync or STARK proof generation. This is design-comparison evidence, not an incident-ranking exercise.

Pinned scope

  • Latest GitHub release v0.2.7, published July30,2026, and independently cloned current main are both cc8e8704026c916d545f02aa4d03b5693b6a58dd. The README's recommendation to checkout release is stale: neither a branch nor tag of that name was returned by git ls-remote; use the actual versioned release as this snapshot. Release, README.
  • Lockfile selects Triton VM7.0.0 from crates.io, twenty-first1.1.0, tasm-lib7.0.0 from XNT's fork at 803223357cc7d50ceba68ea1310911639b86f02f, and CTIDH wrapper revision 77485d0e8262c2edb87e90b51369b12fffbb6d94. No Miden dependency or L2 workspace member appears. dependencies, core manifest.
  • Publicly linked mobile apps really exist: iOS 0.4.6, July23, and Android listing updated July21. The iOS history says its default address switched to Generation on April6 (0.3.2). The linked developer is Jecra/Softly, not the Cash desktop-wallet repository. No corresponding mobile UI source/reproducible source-to-store revision was established through the official organization and linked routes; SDK behavior below must not be silently asserted as the exact app polling/cursor policy. iOS, Android.

Matrix-ready mechanism comparison

Axis Released XNT mechanism Difference from current Cash evidence
Authorization Programmable UTXO lock script, normally a Tip5 preimage predicate inside a Triton STARK; claim public input binds transaction-kernel MAST hash. Same basic architecture, not a replacement conventional signature. Optional short-address construction has a separate integration failure described below.
Hash/proof assumptions Tip5,40-byte digest; actual Triton7 default security parameter160.18-word master secret represents approximately192 bits. Same Tip5/seed family; Cash latest core uses Triton8. Neither the160 setting nor64-byte isogeny public key establishes a whole-system quantum bit count.
Notifications Default Generation: custom twenty-first lattice KEM + AES-256-GCM. Optional CTIDH512 action-based shared secret + SHAKE256 + AES-256-GCM. CTIDH short addresses and integrated payment-ID subaddresses are genuine XNT additions. Cash's optional EC-hybrid address is a different construction.
Ledger privacy Committed UTXO contents/amounts; public fee, timestamp, structural fields, output commitments and announcement receiver tags. Same fundamental confidentiality model. Homepage claims of no metadata do not match the public header.
Query privacy SDK looks up exact unsalted Tip5(receiver tag), then exact commitments and spent-index hashes. Different from Cash GUI's common stripped-history scan: XNT indexer saves client download while learning recognizable receiver history and queried state identifiers.
Recovery Core scan mode defaults25 future keys; default on-chain payloads support seed-based rediscovery. SDK provides indexed per-key height-range primitives. Do not import Cash GUI's complete reorg/cursor policy into the uninspected XNT mobile UI. Off-chain payload availability remains a separate recovery precondition.
Warm state Core scans new blocks and restores unsynced monitored membership witnesses from archival state at each new tip; SDK can request witnesses by selected inputs. Cash0.17 archival default stores zero proofs and can derive them at spending time. XNT's current core still loops through monitored UTXOs during refresh.
Speed L1 target300,000ms. SDK generates4+L+T component proofs, then upgrading/aggregation is needed for block inclusion. A five-minute target is not proof latency; advertised one-second Miden L2 is not a demonstrated released-XNT end-to-end transfer figure.

Authorization evidence: hash-lock predicate, kernel binding and V2 proving. Seed conversion: 24 bytes /18 words. Triton7 packaged source defaults160 at src/stark.rs:1615–1619; its docs call the parameter conjectured (:61–70). The same approximately192-bit seed permits generic quantum search around2^96 oracle queries given a checkable derived address; that is a theoretical search count, not a practical attack or timing result.

Raw sizes: address, key and notification are separate objects

The synthetic serializer used the exact selected twenty-first1.1.0 dependency, bincode1.3.3, bech32m0.9.1, and XNT's Generation address field order. Sizes are executed measurements of those layouts, not estimates from screenshots.

Object Raw bytes Mainnet text length / structure
Generation lattice public key 2,080 32-byte seed +4×64 Goldilocks coefficients
Generation complete receiving-address payload 2,168 8-byte receiver tag +2,080 key +40 privacy postimage +40 lock postimage; 3,482 bech32m characters
Optional CTIDH512 public key / XNT address payload 64 Public-key-only payload; 116 bech32m characters, including HRP/separator/checksum
Optional CTIDH subaddress payload 72 Same64-byte public key +8-byte payment ID; 130 characters
Generation KEM ciphertext alone 2,560 320 field elements; does not include nonce, encrypted note, or public notification header
CTIDH ephemeral public key alone 64 Its field encoding normally uses9 field elements, plus a separate field counting that encoded length

Generation address fields, Generation serialization, exact lattice key/ciphertext types, short-address encoding, short subaddress encoding.

For exact announcement sizing let P be serialized plaintext bytes, C=P+16 for the AES-GCM tag, and f(n)=1+ceil(n/8)+e(n) field elements, where e counts the encoding's extra escapes for exceptional64-bit chunks. Generation announcement: 323+f(C) fields. CTIDH announcement: 4+f(64)+f(C) fields, normally 13+f(C). Both include two public header fields (type, receiver), a nonce field and encoded encrypted payload. Therefore the same payload saves normally 310 fields /2,480 bytes with CTIDH. These are raw announcement-message fields before outer container serialization; JSON/P2P envelopes add overhead. UTXO payload is variable, so there is no universal complete ciphertext byte count. Generation encryption, CTIDH encryption, escape encoding, public header.

CTIDH: genuine bandwidth benefit, separate parameter and integration questions

XNT's dependency named dctidh512 selects the ctidh512 Rust package: secret74 bytes, public/shared values64 bytes. Its build script specifically builds libhighctidh_512 from the helper tree; do not equate the selected512 backend with the repository README's2047-bit dCTIDH benchmarks. Derivation validates the peer public key before the action. Sending a notification computes an ephemeral public key and a shared-secret action; receiving computes a validated shared-secret action. The short format changes bandwidth and decryption cost; it does not remove receiver discovery or state-witness work. Selected wrapper, actual build target, validate/action.

Do not label this512-bit field as512-bit security or automatically assign present-day NIST category1. Modern CSIDH estimates depend strongly on quantum circuit-depth/resource assumptions; the2024 high-security study considers2048/4096-bit primes for level1 under its specified models. Published2021 CTIDH512 full-keyspace benchmarks report125.53M cycles for action,129.64M with validation on3GHz Skylake; they are historical primitive measurements, not measured XNT mobile timings. High-security CSIDH §3.1, CTIDH2021 Table2. See the parallel CSIDH evidence for model details; no current XNT action benchmark was run.

Separate implementation finding, not an argument against the intended architecture: lock_preimage_from_public_key hashes public address bytes. Both receiver_preimage and unlock_key_preimage are assigned this value; the standard hash-lock witness therefore needs no CTIDH secret. A sender knows the public address, the created UTXO and sender randomness, hence also the ingredients needed to construct its removal indices once its public AOCL position is known. An arbitrary passive observer may still lack the encrypted UTXO/randomness: public lock knowledge does not itself decrypt every note. This construction should not be copied as a secure spend/view separation. public-derived preimage, lock witness and address postimages, input/membership ingredients.

Executed bounded check: 3 synthetic public-derived witnesses accepted by the Triton 7 VM, 3 wrong witnesses rejected, using the copied hash-lock instruction sequence and byte encoding. No recipient secret/action or real address was involved. This validates the predicate boundary, not an executed full-transaction theft or a break of the underlying isogeny problem. Reproduction instructions, source, lockfile and output are retained alongside this report. Generation's separate seed-derived unlock/privacy preimages remain distinct: Generation derivation.

Discovery, recovery and state costs

XNT subaddresses are base address + encrypted payment ID, sharing the base receiver tag and encryption key. They provide payment labeling without deriving another decryption key; they do not make payments to that base tag unlinkable. Core explicitly documents the tag-reuse leak. SDK's lookup hash is calculated from that same public tag, so anyone with indexed announcements can build its exact dictionary. It is not private search or PIR. subaddress base/tag, SDK query identifier, index creation.

Indexer stores receiver/tag history in1,000-block buckets. A query touches each bucket in the requested range and returns matching non-orphaned receipts; service allows at most10,000 blocks of span. Client decrypts returned notes, checks the expected lock, queries exact commitments for AOCL positions and exact spent hashes, then requests candidate membership proofs. A membership verifier is exposed, but the collection helper does not independently authenticate the entire canonical chain or prove that no payment was omitted. bucket lookup, RPC range and exact state queries, SDK collection, membership verifier.

Thus a cold SDK restore can avoid downloading unrelated encrypted payloads: server work includes the requested height buckets; client work scales with searched keys and returned history. Warm callers can request only new ranges, but still need current spend checks/witnesses and a correct persisted reorg cursor. The public SDK primitive does not establish the mobile app's gap limit, poll cadence, historical checkpointing or rollback implementation. The indexer itself filters marked orphaned receipts/spends; that is not proof of a client's complete rollback. Core separately defaults25 future keys and retains on-chain/off-chain notification modes. Seed alone cannot recreate unavailable sender-generated off-chain receipt randomness. core scan defaults, notification payload/modes, indexer spent reversal.

Unlike the latest Cash archival policy, XNT core still calls restore_monitored_utxos_from_archival_mutator_set after each non-genesis tip and traverses monitored UTXOs, refreshing those not synced to the new tip. Reorgs need those older/spent records too. This avoids eager per-addition witness mutation but is not O(1) wallet upkeep or strictly spending-time-only witness recovery. per-tip call, monitored traversal/restoration. Short CTIDH ciphertext does not change this state algorithm.

Performance and L2 status boundary

Released L1 targets five-minute blocks; SDK calls ProofCollection::produce_v2, whose structure is4+L+T proofs and remaps legacy type-script hashes. It is not the current Cash0.17 Delta/Forge path. Mempool acceptance of that collection is not mined settlement. No current XNT matched transfer/restore runtime benchmark was established. L1 target, SDK proving, component count.

The current full-node verification boundary also matters: proofs_are_trusted() returns true for every pre-v7 consensus era, and block validation skips proof re-verification for those eras. This is an explicit historical-proof trust policy, not independently verified-from-genesis soundness; it says nothing by itself about an exploitable current block. Trust selector, validation gate.

An official CUDA prover repository exists at 932f8047a0914f118e35edfd5383dd024cf9b173, but its bundled patch workspace is Triton1.0.0; the public code snapshot alone does not demonstrate compatibility or current performance against XNT's released Triton7. Do not transfer old GPU or Cash proof times to this release. Bundled version.

The official homepage advertises Miden L2 and one-second blocks; the news index describes an evolving unified L1+L2 system. The reviewed release/organization exposes no corresponding L2 verifier/bridge/rollup source or reproducible deployed configuration. Linked article bodies returned HTTP500. Consequently the evidence classification is advertised direction, current released/deployed status unverified, not a measured1s settlement path and not proof that no private implementation exists. Homepage, official news index.

Reproduction: shallow clones of main and v0.2.7, GitHub API release/org metadata, lockfile parsing and source inspection. The standalone predicate/serializer executable passed; its reproduction files are linked above. Downloaded sources and metadata remain in /tmp/mudra-revision-20260912. The research changed audit artifacts only.

Graph