Skip to main content

How Privora Works

Privora is an L2 rollup for Solana that enables Fully Homomorphic Encryption (FHE) computations. This page explains the system architecture and how data flows through the platform.

System Components

Sequencer

The Privora sequencer is the core component that:
  • Receives encrypted data submissions from clients
  • Manages the content-addressable data store
  • Executes FHE operations via the modified Solana runtime
  • Batches and settles transactions to Solana L1

Content-Addressable Store

FHE ciphertexts are stored off-chain in a content-addressable store:
PropertyDescription
KeySHA256 hash of the ciphertext
ValueSerialized FHE ciphertext (10KB-100KB)
AccessPrograms fetch via fetch_data(hash) syscall
This design keeps on-chain storage minimal (32-byte hashes) while supporting large ciphertexts.

FHE Runtime

The FHE runtime extends the Solana BPF VM with:
  • Custom syscalls for FHE operations (sol_fhe_add, sol_fhe_mul, etc.)
  • Extended heap size (~1MB) for ciphertext processing
  • Integration with the TFHE library for actual computations

Data Flow

Encryption and Submission

  1. Client encrypts a value using the sequencer’s FHE public key
  2. Client submits the ciphertext to the sequencer
  3. Sequencer computes SHA256 hash of the ciphertext
  4. Ciphertext is stored in the content store
  5. Hash is returned to the client for use in transactions

Program Execution

  1. Client sends transaction containing hash references to encrypted data
  2. Program loads encrypted values using EncryptedRef::load()
  3. Runtime fetches ciphertexts from the data store
  4. FHE operations are performed on the encrypted data
  5. Results are stored back via Encrypted::store()
  6. New hash references are saved in program accounts

Decryption

Decryption can happen through two paths:
For values encrypted with dual encryption, users can decrypt locally:This is instant and doesn’t require network calls.

Account Layout

Privora programs use a specific account layout:
/// On-chain account structure
#[derive(BorshSerialize, BorshDeserialize)]
pub struct PrivoraAccount {
    // Regular Solana account fields
    pub owner: Pubkey,              // 32 bytes
    pub status: u8,                 // 1 byte

    // Hash references to encrypted data (NOT the ciphertext!)
    pub encrypted_value: EncryptedRef<u64>,  // 32 bytes (just the hash)
    pub encrypted_flag: EncryptedBoolRef,    // 32 bytes
}
Key insight: On-chain accounts store only 32-byte hash references, not the actual ciphertexts. This keeps rent costs low and allows ciphertexts of any size.

Security Model

Trust Assumptions

ComponentTrust LevelNotes
SequencerSemi-trustedCannot see plaintext; can censor or reorder
MPC NetworkThreshold trustk-of-n nodes must collude to decrypt
FHE KeysDistributedKey generation ceremony
User KeysUser-controlledX25519 keys for recovery

Data Privacy

  • Encrypted data: Only hash references are on-chain; ciphertexts are off-chain
  • Computation privacy: FHE operations never expose plaintext
  • Access control: Authorization PDAs control who can request decryption
  • User recovery: Optional X25519 encryption for instant local decryption

Comparison with Other Approaches

ApproachComputation PrivacyVerifiabilityPerformance
Privora (FHE)FullYesModerate
TEE (SGX)Depends on HWLimitedFast
ZK ProofsLimited to proofsYesSlow
MPC OnlyFullYesVery slow
Privora combines FHE for computation privacy with optional MPC for key management and decryption, balancing security and performance.

Next Steps