Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Ciphertext Accounts

Pre-Alpha Disclaimer: This is an early pre-alpha release for exploring the SDK and starting development only. There is no real encryption — all data is completely public and stored as plaintext on-chain. Do not submit any sensitive or real data. Encryption keys and the trust model are not final; do not rely on any encryption guarantees or key material until mainnet. All interfaces, APIs, and data formats are subject to change without notice. The Solana program and all on-chain data will be wiped periodically and everything will be deleted when we transition to Encrypt Alpha 1. This software is provided “as is” without warranty of any kind; use is entirely at your own risk and dWallet Labs assumes no liability for any damages arising from its use.

Structure

Ciphertext accounts are regular keypair accounts (not PDAs). The Encrypt program is the Solana owner.

FieldSizeDescription
ciphertext_digest32Hash of the encrypted blob (zero until committed)
authorized32Who can use this (zero address = public)
network_encryption_public_key32FHE key it was encrypted under
fhe_type1Type discriminant (EBool=0, EUint64=4, etc.)
status1Pending(0) or Verified(1)

Total: 98 bytes data + 2 bytes prefix (discriminator + version) = 100 bytes.

Account Pubkey = Identifier

The account’s Solana pubkey IS the ciphertext identifier. There is no separate ciphertext_id field. This means:

  • Client generates a keypair for each new ciphertext
  • The pubkey is used in events, store lookups, and all references
  • Update mode reuses the same account (same pubkey, new digest)

Creating Ciphertexts

Authority Input (create_input_ciphertext, disc 1)

User encrypts off-chain → submits to executor with ZK proof → executor verifies → calls this instruction. Status = Verified.

Plaintext (create_plaintext_ciphertext, disc 2)

User provides plaintext value directly. Executor encrypts off-chain and commits digest later. Status = Pending until committed.

#![allow(unused)]
fn main() {
ctx.create_plaintext_typed::<Uint64>(&0u64, ciphertext_account)?;
}

Graph Output (execute_graph, disc 4)

Computation outputs are created automatically by execute_graph:

  • New account (empty) → creates Ciphertext with status=Pending
  • Existing account (has data) → resets digest/status (update mode)

Status Lifecycle

Created (by execute_graph) → PENDING → commit_ciphertext → VERIFIED
Created (by create_input)  → VERIFIED (immediately)
Created (by plaintext)     → PENDING → commit_ciphertext → VERIFIED