Arcium provides computational privacy through MPC. Security depends on:
- At least 1 honest ARX node (Cerberus protocol)
- Correct encryption/nonce usage
- Proper account validation
- Sound circuit design
- Dishonest majority: tolerates N-1 malicious nodes
- Requires only 1 honest node
- MAC-based authentication
- Abort-on-cheat detection
- Honest-but-curious only
- Requires trusted dealer
- Use only for trusted operator scenarios
Risk: Reusing nonce with same key completely breaks encryption.
Prevention:
// Always store and update nonce
ctx.accounts.state.nonce = output.nonce;// Always generate fresh nonce
const nonce = randomBytes(16);Risk: Shared secret exposure allows decryption of Enc<Shared, T>.
Prevention:
- Use ephemeral keys when possible
- Use
Enc<Mxe, T>for protocol state users shouldn't decrypt - Implement key rotation for long-lived applications
Risk: Both branches always execute, but selection can leak through output.
Bad Pattern:
// Leaks whether amount > threshold
if amount > threshold {
transfer(amount)
} else {
reject()
}Better Pattern:
// Always perform same operations
let should_transfer = amount > threshold;
let transfer_amount = if should_transfer { amount } else { 0 };
// Always call transfer, but with 0 if rejectedRisk: Variable execution time leaks information.
Protection: Arcis uses constant-time operations. Don't circumvent with:
- Early returns based on secrets
- Variable loop iterations
Risk: O(n) complexity reveals array size, not index.
Note: This is safe - all positions checked regardless of actual index.
Risk: Fake accounts with correct structure pass deserialization.
Prevention:
// Use typed accounts
pub state: Account<'info, GameState>,
// Or explicit check
#[account(owner = program_id)]
pub state: UncheckedAccount<'info>,Risk: Attacker passes wrong accounts to callback.
Prevention:
// Validate PDA seeds
#[account(
seeds = [b"game", game_id.to_le_bytes().as_ref()],
bump = state.bump,
)]
pub state: Account<'info, GameState>,Risk: Valid accounts but wrong relationships.
Prevention:
#[account(
has_one = authority,
constraint = state.game_id == expected_game_id,
)]
pub state: Account<'info, GameState>,- Input values during computation
- Intermediate computation values
- Output values (if encrypted)
- Transaction metadata (who called, when)
- Account existence and addresses
- Public parameters
- Revealed values
Risk: Timing, frequency, and parties reveal information.
Mitigation:
- Batch operations
- Use relayers/proxies
- Randomize timing where possible
// BAD: Reveals exact balance
let balance = encrypted_balance.to_arcis();
balance.reveal()
// BETTER: Reveal only what's needed
let sufficient = balance >= required_amount;
sufficient.reveal()Risk: Seeing encrypted bid transaction allows front-running.
Mitigation:
- Commit-reveal schemes
- Randomized submission windows
- MEV protection
Risk: Reusing computation with same inputs.
Prevention:
- Include unique nonce/timestamp in inputs
- Track computation offsets
Risk: State changed between queue and callback.
Prevention:
- Validate state version/nonce in callback
- Use atomic state updates
- No unnecessary reveals
- Constant-time operations (no early exits on secrets)
- Bounded loops only
- No variable-length data structures
- Fresh nonce for every encryption
- Correct owner type (Shared vs Mxe)
- Key rotation strategy for long-lived apps
- Owner validation on all accounts
- PDA seed validation
- Relationship validation (has_one, constraints)
- Pre-created callback accounts with correct size
- Use Cerberus backend for DeFi
- Validate program IDs for CPIs
- Handle computation abort gracefully
- Update nonce after each computation
- Generate fresh nonces
- Secure key storage
- Handle MXE public key fetch failures
- Verify decrypted results
- What can an observer learn from transaction metadata alone?
- What values are revealed vs. kept encrypted?
- Can computation results be replayed?
- Are all account relationships validated?
- Is the nonce management correct?
- Could timing or frequency patterns leak information?
- What happens if MPC computation aborts?