This page records the rationale for each major design decision in Rand: the property a component must provide, the assumption under which it provides it, and the cost accepted in exchange. It was compiled on 29 September 2026 from this site, the whitepaper summary and the reference full node (github.com/randprotocol/fullnode: its README, docs/ and docs/superpowers/specs/). Each answer cites the document in which the rationale is stated; paths refer to the fullnode repository unless they begin with randprotocol.org.
Status. Rand runs on a testnet operated by the founding team, and the protocol has not been independently audited. Several decisions below are implemented in stages across chain cuts. All figures are measurements of the running node at the time of compilation; they are expected to change and should be re-measured before being cited.
Cryptographic primitives
1. Why ML-KEM-768 (Kyber) for note encryption?
A note’s plaintext is encrypted to its recipient in an envelope that remains on the public ledger indefinitely. Its confidentiality is therefore an irrevocable property (question 8): an adversary who obtains a cryptographically relevant quantum computer at any later time could decrypt every historical envelope sealed under an elliptic-curve KEM, since Shor’s algorithm solves the discrete logarithm in polynomial time. ML-KEM is standardised in NIST FIPS 203 and its security reduces to Module-LWE, for which no efficient quantum algorithm is known. The 768 parameter set (NIST category 3) was selected as the trade-off between security margin and the 1,184-byte encapsulation key that every address must carry. The envelope is ML-KEM-768 combined with ChaCha20-Poly1305: 1,348 bytes, or 1,860 bytes with the fixed memo field.
Source: randprotocol.org (post-quantum section); fullnode README; docs/shielded.md §2
2. Why Poseidon2 commitments rather than Pedersen?
Pedersen commitments are perfectly hiding but only computationally binding, and their binding reduces to the discrete-logarithm assumption, which a quantum adversary breaks; an adversary able to compute discrete logarithms can open a commitment to a different value. Because a commitment published today must remain sound and hiding for the lifetime of the ledger, the scheme must rest on assumptions believed to hold against quantum adversaries, which in practice means a hash function. Poseidon2 is an arithmetisation-oriented hash defined over the Goldilocks field, so evaluating it inside the STARK costs few constraints. The same hash instantiates the note commitment, the depth-32 Merkle tree and the nullifier.
Source: randprotocol.org (post-quantum section); docs/shielded.md §1–2
3. Why two hash functions — BLAKE3 and Poseidon2?
The two functions are optimised for different cost models. Poseidon2 is used wherever a hash must be evaluated inside a proof — notes, the commitment tree, nullifiers and the zkVM’s internal tables — because its cost is measured in constraints. BLAKE3 is used wherever no proof is involved and native throughput dominates: block hashes, the state root over the tree, nullifier set, validator register and program table, and validator addresses (the BLAKE3 digest of the public key). Poseidon2 is comparatively slow on a CPU; BLAKE3 is comparatively expensive to arithmetise. Each is used only where its cost model applies.
Source: fullnode README (signatures / hashes row); docs/architecture.md
4. Why Dilithium2 (ML-DSA) for validator signatures?
Consensus signatures provide a renewable property (question 8): a later break of the scheme permits forgery of future messages but does not retroactively invalidate blocks already finalised, so the scheme could in principle be replaced before a quantum adversary exists. A lattice scheme was nevertheless adopted from genesis so that consensus votes, the bridge guardians’ co-signatures and the validator register share a single post-quantum key type. The node implements the round-3 Dilithium2 parameter set (the crystals-dilithium crate), which differs from the final FIPS 204 ML-DSA-44; public keys are 1,312 bytes and signatures 2,420 bytes.
Source: docs/superpowers/specs/2026-09-19-pq-cosignature-bridge.md §2; randprotocol.org
5. Why a transparent STARK (FRI over Goldilocks) rather than a SNARK?
The choice follows from three requirements. First, no trusted setup: soundness rests only on the collision resistance of a hash function, not on a structured reference string or a pairing-friendly curve. Second, plausible post-quantum soundness: the argument makes no discrete-logarithm or pairing assumption. Third, compatibility with the hash-based commitment scheme of question 2. The cost is proof size: a bundle proof is approximately 1.3 MB, 300–600 times the size of a Zcash or Monero shielded transaction. This cost was accepted and is addressed separately by block-level aggregation (questions 31 and 34).
Source: randprotocol.org; docs/block-space.md §1; docs/zkvm.md
6. Why the 80-query FRI profile instead of 27?
The production profile (80 queries, blowup factor 8, 20 bits of proof-of-work grinding) provides approximately 86 bits of provable soundness, against approximately 42 bits for the 27-query profile, at 2.75 times the proof size. Verification time is nearly unchanged: 809 ms rising to 838 ms cold, and approximately 16 ms warm. Provable soundness was given priority over proof size, and the size cost was transferred to the block-space and aggregation design.
Source: docs/block-space.md §1, §3
7. Why is the post-quantum claim stated per primitive rather than ‘protocol-wide 128-bit’?
Earlier drafts asserted 128-bit post-quantum security for the protocol as a whole. That claim is inconsistent with the Brassard–Høyer–Tapp bound, under which a quantum adversary finds collisions in a 256-bit hash in about 2^85 queries, so it was withdrawn rather than qualified. The paper now states security per primitive and per role — a 384-bit transcript hash, 256-bit hashes used only where preimage resistance is required, Dilithium2, ML-KEM-768, and FRI over an extension field — under the Module-LWE and Module-SIS assumptions with hash functions modelled as quantum random oracles. The node’s transcript hash is currently Poseidon2; the documentation lists this as an open configuration gap.
Source: randprotocol.org (post-quantum section)
8. What is the ‘irrevocable vs renewable’ classification and why does it drive choices?
A security property is irrevocable if an adversary who acquires a new capability at any future time can violate it retroactively for data already published; note confidentiality and commitment hiding are of this kind, so they must be quantum-resistant at the time of publication. A property is renewable if it is re-established at each use, so that a scheme can be replaced before the threat materialises; signatures and proof soundness are of this kind. Each primitive choice in this section follows from classifying the property it protects.
Source: randprotocol.org (post-quantum section)
The shielded pool
9. Why a note/UTXO model with no accounts or balances?
An account-based ledger publishes balances by construction; concealing them requires encrypting the state and proving statements over the ciphertexts, which is substantially more expensive. A note pool stores only commitments and nullifiers, neither of which reveals an owner or an amount, so the public state contains no balance information. The single exception is the validator register, whose stake weights must be public so that replicas agree on quorum membership (question 29).
Source: docs/shielded.md §1–2; docs/staking.md §1
10. Why is the address ~1.6 KB?
A shielded address consists of the 32-byte owner field pk and the 1,184-byte ML-KEM-768 encapsulation key that a sender needs to seal the envelope; base58-encoded, this is approximately 1,667 characters. The length is a direct consequence of the post-quantum KEM. An approved design (short shielded addresses, 2026-09-17) replaces the address with a receiver identifier of about 256 bits that resolves to an updatable record, signed with the spend key and served by the explorer, so that the encapsulation key is fetched rather than transcribed.
Source: docs/shielded.md §1; docs/superpowers/specs/2026-09-17-short-shielded-address.md
11. Why is every key derived from one 256-bit spend key?
All other key material is a deterministic function of a single secret sk: the viewing key nk = H(NK, sk), the owner field pk = H(PK, nk), the nullifier H(NF, nk, cm), the outgoing viewing key and the ML-KEM decapsulation key, each under its own domain separator. The key file therefore stores only sk, a backup is a single value, and rescanning the tree from leaf 0 recovers every note. Because there is no second copy from which to recover, the wallet refuses to overwrite an existing key file.
Source: docs/shielded.md §1
12. Why a fixed 4-in-4-out bundle shape?
A fixed shape makes every bundle the same size and structure regardless of what it moves. Each bundle publishes exactly four nullifiers and four commitments; unused slots are zero-value dummy notes, and the change output is published even when its value is zero, since an absent change output would distinguish the transaction. The original specification was 2-in-2-out, following Sapling. It was widened to 4-in-4-out with the hidden-asset bundle, so that slots 0–1 carry a private asset and slots 2–3 carry RAND for the fee; four slots rather than three allow a token transfer to fund its fee from up to two RAND notes.
Source: docs/shielded.md §2; docs/superpowers/specs/2026-09-19-hidden-asset-bundle-design.md §3
13. Why does one proof move any asset (RAND, zUSD, RPL tokens)?
Before chain 14, a token transfer carried two bundles, one for the RAND fee and one for the asset, which required two proofs and revealed to any observer which token had moved. The hidden-asset guest takes the asset identifier as a private input, so a zUSD transfer is indistinguishable from a RAND payment. The guest fits at tier 14 (approximately 100 s and 5.7 GB of memory) only because it reads its inputs in a loop and fuses the Merkle membership check; a fully unrolled implementation requires tier 16 (approximately 400 s and 21 GB), which exceeds the memory of a 16 GB machine.
Source: docs/superpowers/specs/2026-09-19-hidden-asset-bundle-design.md §1–3
14. Why is the fee public and paid to the proposer?
A public fee is consistent with the public stake register and makes admission inexpensive: a node can check the fee floor before performing any verification. The bundle proof enforces the balance equation Σ inputs = Σ outputs + fee + burn, so the fee is paid from hidden notes without revealing which notes. The accepted cost is that the fee amount may reveal the class of transaction (transfer or program call).
Source: docs/superpowers/specs/2026-09-11-shielded-pool-design.md (rulings table); docs/fees.md §1
15. Why do deposits (mint, bridge attest) have a public amount?
Value entering the pool must be accounted for publicly, and the bridge attestation is the public evidence that a corresponding lock occurred on the source chain. The resulting visibility is limited to the entry step, analogous to a transparent-to-shielded (t-to-z) transaction in Zcash; subsequent spends of the deposited note are hidden.
Source: docs/superpowers/specs/2026-09-11-shielded-pool-design.md; docs/shielded.md (what is public table)
16. Why is the memo a fixed 512-byte field?
A fixed-length field ensures that the ledger does not reveal whether a memo is present or how long it is: on a memo-enabled chain every note-creating envelope, including dummies and change, is exactly 1,860 bytes. The memo is carried only inside the encrypted envelope, never in the note, the commitment or the proof, and is readable by exactly the parties who can already decrypt the note. A malformed memo is decoded as an empty memo, so that it cannot render the note itself unrecoverable.
Source: docs/shielded.md §2; docs/superpowers/specs/2026-09-26-address-sharing-and-memo-design.md
17. Why is proving local, and how does the delegated prover not break that?
The proof itself is the spending authorisation: a bundle carries no signature and no sender field, so the spend key need never leave the wallet. A tier-14 bundle proof requires approximately 5.7 GB of memory, which exceeds what phones and browsers can provide, hence the delegated prover. Split authorisation (bundle guest v3, genesis parameter hc_auth) separates the two roles: the prover receives only the viewing key nk and produces the bundle proof, while the wallet produces a small tier-10 authorisation proof using sk. A prover can therefore construct a bundle proof but cannot authorise a spend (question 36).
Source: docs/prover.md §1; docs/shielded.md (split authorisation); docs/superpowers/specs/2026-09-28-delegated-proving-design.md
18. Why an anchor window of 256 blocks?
A proof is constructed against a particular commitment-tree root (its anchor), and constructing a tier-14 bundle proof takes approximately 100 s. The ledger must therefore accept anchors that are several minutes old at the time of submission. The window was 64 blocks in the original specification and was widened to 256 blocks as the block interval decreased, keeping its duration in wall-clock time above the proving time.
Source: docs/shielded.md; docs/superpowers/specs/2026-09-11-shielded-pool-design.md
The zkVM and confidential computation
19. Why RV32I as the guest ISA (and not RV64)?
A 32-bit word decomposes into exactly four byte limbs, and the Goldilocks prime p = 2^64 − 2^32 + 1 is large enough that the product of two 32-bit values never overflows the field. RV64 would double the number of limb columns in the ALU and memory tables. RISC-V is also an existing target of mainstream compilers, so guest programs are ordinary compiled binaries rather than programs in a purpose-built language.
Source: docs/zkvm.md §2; research/docs/01-isa.md (‘Why RV32, not RV64’)
20. Why Goldilocks rather than a 256-bit field?
Goldilocks is a 64-bit prime whose arithmetic maps efficiently onto native 64-bit CPU instructions, and whose multiplicative group has a large power-of-two subgroup, as FRI requires. Together with 32-bit words, it keeps every trace row narrow, which makes production-profile proving feasible on a laptop. The soundness lost by working over a small field is recovered by drawing FRI challenges from an extension field.
Source: docs/zkvm.md §2; randprotocol.org (performance section)
21. Why gas tiers instead of per-opcode gas metering?
Per-opcode gas exists in Ethereum because every node re-executes every transaction and execution length is not bounded in advance. In Rand no node executes a program: the sender executes it once, off chain, and nodes verify a single STARK whose verification cost depends only on the tier, not on the computation performed. Termination is enforced by the tier, since an execution that does not halt within 2^t cycles admits no proof at tier t. Pricing is a flat floor plus a gas estimate bounded by the header, and block capacity is a byte budget. Gas appears only inside the EVM and sBPF interpreter guests, as private state, where it is needed to reproduce the source chain’s semantics.
Source: docs/fees.md §3–4; docs/superpowers/specs/2026-09-28-gas-model-design.md
22. Why is the trace split into nine tables joined by LogUp buses?
A single monolithic table would pad every row to the width of the widest operation. Separating the trace into nine tables — CPU, memory, ALU, range, nibble, Poseidon2, program, input and public — each padded only to its own height, keeps the total trace small. LogUp arguments establish the multiset relations between the tables. Keccak and SHA-256 tables are optional and are included only when the guest invokes the corresponding system call.
Source: docs/zkvm.md §5
23. Why does a program call publish only eight output words?
A program call is a proof that public code was executed correctly on private inputs; the ledger records only the receipt. Eight 32-bit words suffice to bind a result, a commitment or a decision, and a fixed output size ensures that the shape of the receipt reveals nothing about the program. Outputs are currently data only: a program cannot itself transfer value.
Source: randprotocol.org/usecases (platform note); docs/confidential.md
24. Why is there a call-input envelope?
A caller who retains the private inputs can later demonstrate what a call was computed over. The call-input envelope makes this durable by storing the inputs, encrypted, alongside the call, where a designated auditor can decrypt them with a key. This extends selective disclosure — confidential to the market, open to a designated regulator — from payments to program execution.
Source: docs/confidential.md (‘Call input envelopes’)
25. Why is a constraint-set change a hard fork?
Every node re-verifies every proof during synchronisation, and a proof is valid only with respect to the constraint set (AIR) under which it was produced. A change to the AIR therefore changes the set of valid chains, and it is introduced at a genesis cut rather than adopted node by node.
Source: docs/architecture.md (‘Why a constraint-set change is a hard fork’)
26. Why is the emulator the reference, not the AIR?
The emulator is the readable specification of the machine and the AIR is an encoding of that specification as polynomial constraints. Where the two disagree, the AIR is by definition in error. This places the normative definition in the artefact that is most practical for humans to audit.
Source: docs/zkvm.md §5
Consensus and the node
27. Why chained HotStuff BFT?
Chained HotStuff provides deterministic finality: with stake-weighted quorums of more than two thirds, a block is final once three consecutive quorum certificates have been formed on top of it, and a final block is never reorganised. The measured block interval is 1.2 s and the time to finality approximately 3.6 s. The intended institutional users require settlement finality against which they can record entries, which a chain with probabilistic finality does not provide.
Source: fullnode README; randprotocol.org (performance section); docs/architecture.md §6
28. Why is proof verification off the consensus loop?
A node verifies each STARK when it admits the transaction (approximately 32 ms warm), before relaying it, so verification never lies on the critical path of block proposal. The block interval is therefore determined by consensus latency rather than by proof size. Checks are ordered by cost, with the STARK verified last, so that a malformed transaction is rejected before the most expensive step.
Source: randprotocol.org; docs/architecture.md (‘How it works’)
29. Why is the validator register public when everything else is shielded?
All replicas must agree on which validators may propose and which votes constitute a quorum, which requires stake weights to be public. The register therefore holds stake amounts in the clear. The link to ownership remains hidden: a bond is funded from a shielded note and a withdrawal is paid into one, and neither operation reveals whose note it is.
Source: docs/staking.md §1
30. Why does a syncing node re-execute every block instead of trusting certificates?
A node that joins late verifies every quorum certificate, re-verifies every bundle and call proof, and compares the resulting receipts before accepting the chain. Because validity is established by the proofs rather than by signatures alone, this procedure is not exposed to the long-range attacks that affect chains secured only by signatures. Pruning proofs from history was rejected because it would remove this guarantee.
Source: docs/architecture.md; docs/aggregation.md (introduction)
31. Why keep the block cap at 4 MiB when a proof is over 1 MB?
With a fixed cap, block size cannot grow; when demand exceeds capacity, throughput is limited instead (to three shielded transfers per block under the 80-query profile). A throughput limit was judged a safer failure mode than unbounded block growth. The chosen remedy is block-level aggregation, one recursive proof per block, rather than raising the cap or reducing the soundness level.
Source: docs/block-space.md §1, §6
32. Why does the testnet prune history to one day?
A quorum certificate carrying 18 Dilithium2 signatures is approximately 44 KB and is stored twice per block. With mostly empty blocks every 1.4 s, this amounted to approximately 6.6 GB per node per day; node disks filled, and the chain lost quorum at height 248,953. Testnet full nodes now retain one day of history, a single archive node retains all of it, and mainnet nodes will retain all of it. Ledger state — the tree, nullifier set, register and programs — is never pruned.
Source: docs/superpowers/specs/2026-09-24-history-pruning-design.md
33. Why libp2p?
The node uses TCP with Noise and Yamux, gossipsub for transactions and votes, Kademlia with a bootstrap list for peer discovery, mDNS on local networks, and request-response for block synchronisation. These are standard, widely deployed components, so the node inherits peer scoring, reconnection and transport upgrades rather than maintaining its own implementations.
Source: fullnode README (networking row)
Proving market and aggregation
34. Why block-level proof aggregation?
Block space grows linearly with the number of bundles if each carries its own proof of approximately 1.3 MB. A single recursive STARK per block, verifying all N bundle proofs, keeps the on-chain proof cost constant in N. Validators then verify one aggregate proof (approximately 16 ms warm) on a CPU, so commodity hardware can still validate, while aggregators with GPUs compete in a separate permissionless market for the proving share of fees and a block subsidy.
Source: docs/aggregation.md §1
35. Why three roles — validator, aggregator, delegated prover?
The three roles have different hardware requirements and are paid by different parties. A validator orders and verifies transactions on a CPU and is paid from the verification share of fees. An aggregator produces the recursive block proof on a GPU and is paid from the proving share and the subsidy. A delegated prover produces a single bundle proof for a sender whose device cannot (a phone or browser) and is paid privately by that sender. Separating the roles keeps validation inexpensive and makes proving competitive.
Source: docs/prover.md §1
36. Why can a delegated prover not steal funds?
Under split authorisation the prover receives the viewing key nk but not the spend key sk. The bundle proof commits to c = H(AUTH, nk || salt), and the wallet’s separate authorisation proof demonstrates knowledge of sk for the same c. Without sk the prover can compute the bundle proof but cannot produce a valid authorisation, and the wallet verifies the returned proof before submitting it.
Source: docs/shielded.md (split authorisation); docs/prover.md §8
The bridge and zUSD
37. Why lock USDT/USDC on their home chains instead of issuing a new stablecoin?
Native issuance on Rand would make reserve capacity contingent on the issuers’ deployment decisions, which are outside the project’s control. Locking USDT and USDC on Ethereum, BSC, Tron and Solana draws reserves from the chains on which these assets already circulate and introduces no new issuer: each zUSD unit is a claim on USDT or USDC held in a publicly readable custody contract.
Source: randprotocol.org (reserve section)
38. Why a t-of-n guardian set, and why say so plainly?
The attestation is the only evidence available to Rand that a lock occurred on another chain, so it must be signed by a threshold group; a valid attestation requires signatures from more than two thirds of the guardians. The resulting trust assumption is stated explicitly. The effective guarantee is the weaker of reserve solvency and bridge integrity; a coalition of t guardians can authorise minting without a corresponding lock; and the exposure is bounded by the custody held on each chain. This assumption was originally the argument against building a bridge. It is not withdrawn but accepted in exchange for reserve capacity.
Source: randprotocol.org (reserve section, ‘What this costs’)
39. Why a Dilithium2 co-signature beside the ECDSA attestation?
The source chains provide no lattice-signature verifier, so releases on those chains remain secured by classical ECDSA, with exposure bounded by custody and caps. Every message that the Rand ledger accepts from the guardians — deposits and guardian-set rotations — must additionally carry a quorum of Dilithium2 signatures from the same guardians. The mint path is therefore post-quantum even though the external endpoints are not. The co-signatures are transmitted alongside the attestation and require no change to the deployed contracts.
Source: docs/superpowers/specs/2026-09-19-pq-cosignature-bridge.md §1
40. Why is the deposit note’s blinding derived rather than chosen?
Previously the deposit note’s commitment was not determined until a relayer submitted the attestation, so two relayers could submit the same attestation with different notes. Deriving the blinding factor r deterministically from the attestation fixes the commitment, so competing submissions collide on a single commitment and the deposit cannot be minted twice.
Source: docs/bridge.md (F1, chain 14)
41. Why can USDT locked on Tron exit as USDT on Ethereum?
zUSD is fungible: each unit is a claim on the aggregate reserve, not on the chain through which it entered. Decoupling entry from exit allows liquidity to move to where it is demanded, subject to the destination chain holding sufficient reserves. The stablecoin paper proves that the invariant S ≤ Σ_c R_c, total supply bounded by the sum of per-chain reserves, is preserved by every state transition.
Source: randprotocol.org (reserve section)
42. Why does shielding hide distribution but not quantity?
Total zUSD supply is public in the token registry and each chain’s reserve is a public balance, so solvency can be verified by anyone; what is hidden is the distribution of holdings among owners. One limitation applies: the four reserve balances cannot be observed atomically at a single instant, so for those chains the check detects insolvency after the fact rather than preventing it.
Source: randprotocol.org (reserve section)
43. Why is a burn the one transaction that names its asset?
A burn releases a specific asset on a specific chain, so the custody contract must learn which asset and which chain. Every other transaction transfers an unidentified asset. The burn also carries the bridge fee, because it is the only bridge transaction whose sender is the beneficiary.
Source: docs/architecture.md; docs/shielded.md §2
Compliance and disclosure
44. Why viewing keys rather than ‘private from everyone’?
Regulators have not accepted privacy systems in which disclosure depends on the cooperation of the party under investigation, as the case of Tornado Cash illustrates. Rand therefore treats disclosure as a protocol object. The holder, or a regulated intermediary, retains a viewing key; an auditor can decrypt the transactions named in a lawful request; and the design target is scoped keys that reveal counterparty and amount without revealing trading strategy. For applications such as payroll, this auditability is a requirement rather than a limitation.
Source: randprotocol.org/usecases (regulation section; payroll case)
45. Why is the outgoing viewing key separate from the incoming one?
Separation allows a sender to prove what it paid without gaining access to the recipient’s history, and the converse. The outgoing viewing key ovk decrypts envelopes the wallet has sent; the ML-KEM decapsulation key decrypts envelopes sent to it; and a per-transaction key discloses exactly one output to a third party.
Source: docs/shielded.md §1–2
Known limitations
46. What do the proofs leak today, and why is it documented?
The review of 2026-09-27 found that under the v1 guest (chains 14–15) each bundle proof reveals which input slots hold real notes and the Hamming weight of each spent leaf index. The cause is twofold: per-table LogUp totals are published without blinding, and the guest’s control flow branches on whether an input is a dummy. The remedy is a branch-free guest (v2), to be selected at the next genesis. The finding is published because the network is a testnet and the documentation serves as its audit record.
Source: docs/shielded.md (‘What the proofs leak today’)
47. Why is state growth under-priced?
Ethereum prices storage writes because stored state imposes a permanent cost on every node. Rand currently prices growth of the commitment tree, the nullifier set and program storage only through the per-word deployment fee and the flat bundle fee. This is adequate for a testnet but is recorded as an open pricing question to be resolved before mainnet; its resolution does not require per-opcode metering.
Source: docs/fees.md §3 (caveats)
48. Why has no independent audit been completed yet?
The protocol is under active development on a testnet operated by the team, and further constraint sets and chain cuts are expected before the design is stable. The website states this on every page. The internal audit rounds (v3–v5) are published in docs/consensus.md and the design specifications, so that the eventual external audit has a complete record to work from.
Source: randprotocol.org (footer); docs/consensus.md