Skip to main content
The following types are supported:
  • u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize
  • f64, f32 (emulated as fixed-point with 52 fractional bits; supported range is [-2^75, 2^75). Values outside this range are unsupported.)
  • tuples of supported types, including ()
  • fixed-length arrays of a supported type
  • slices with compile-time known length (e.g., &arr[..] from fixed arrays, or &[u8] parameters in stdlib APIs like SHA3)
  • compile-time known ranges
  • (mutable) references to a supported type
  • user-defined structs of supported types
  • user-defined enums of supported types (but not as input or output of an encrypted instruction; explicit discriminants are unsupported)
  • Option<T> of a supported type (but not as input or output of an encrypted instruction)
  • functions (but not as input or output of an encrypted instruction)
  • ArcisX25519Pubkey, an Arcis public key wrapper.
  • Arcis-defined Enc, Mxe and Shared.
  • Pack<T>, a wrapper for bit-packing data into fewer field elements for onchain storage.
  • EncData<T>, encrypted data without embedded cipher info. Use with .to_arcis_with_pubkey_and_nonce() when multiple values share the same key.
  • BaseField25519, integers modulo 2^255 - 19. The native field element for Arcis MPC circuits. Supports arithmetic (+, -, *, negation), unsigned comparisons, and field division methods. Construct via BaseField25519::from_u64(x) (and similar from_* methods); extract via .to_u64_unchecked() (only when the value fits the target type — out-of-range values silently produce incorrect results). See Primitives.
Float emulation: Arcis emulates f64/f32 as fixed-point with 52 fractional bits. This differs from IEEE 754 floats:
  • Different precision characteristics than standard floats
  • Supported range: [-2^75, 2^75)
  • Float literals outside this range produce a compile-time error: "Arcis only supports inputs in the range [-2**75, 2**75)"
  • Computed values outside this range are silently clamped to the boundary values

Encryption types

TypeDescription
Enc<Shared, T>Encrypted data shared between client and MXE
Enc<Mxe, T>Encrypted data for MXE only
EncData<T>Raw encrypted data (advanced use, see below)
SharedOwner type for client-shared encryption
MxeOwner type for MXE-only encryption
The Owner type parameter determines who can decrypt:
  • Shared: Both client and MXE can decrypt. Use for user inputs/outputs that need client-side verification.
  • Mxe: Only the MXE cluster can decrypt. Use for internal protocol state that users should not access.

Public key types

TypeDescription
ArcisX25519PubkeyArcis X25519 public key wrapper
SolanaPublicKeySolana public key (32 bytes)
SerializedSolanaPublicKeySerialized form using {lo: u128, hi: u128}

Example

use arcis::*;

#[encrypted]
mod types_example {
    use arcis::*;

    #[derive(Copy, Clone)]
    struct GameState {
        score: u64,
        level: u8,
    }

    #[instruction]
    fn example(
        user_data: Enc<Shared, u64>,
        state: Enc<Mxe, GameState>,
    ) -> Enc<Shared, u64> {
        let value = user_data.to_arcis();
        user_data.owner.from_arcis(value * 2)
    }
}

Advanced: EncData<T>

EncData<T> stores just the encrypted ciphertext without encryption metadata (pubkey + nonce).
TypeContainsSize
Enc<Shared, bool>pubkey (32B) + nonce (16B) + ciphertext (32B)~80 bytes
EncData<bool>ciphertext only~32 bytes
EncData<T> omits pubkey and nonce metadata, useful for multiple outputs where callback payload size matters.

Primary use: smaller callback payloads

Use EncData<T> when returning encrypted data to observers to reduce callback payload size:
#[instruction]
pub fn check_solana_public_key_equality(
    encrypted_pk1: Enc<Shared, SerializedSolanaPublicKey>,
    encrypted_pk2: Enc<Shared, SerializedSolanaPublicKey>,
    observer: Shared,
) -> EncData<bool> {
    let pk1 = SolanaPublicKey::from_serialized(encrypted_pk1.to_arcis());
    let pk2 = SolanaPublicKey::from_serialized(encrypted_pk2.to_arcis());
    let res = pk1 == pk2;
    observer.from_arcis(res).data  // Extract .data from Enc
}
When to use EncData output: Multiple return values where encryption metadata would be redundant.
When returned from circuits, EncData<T> generates EncDataStruct<N> in your Solana program, where N is the number of field elements in T (e.g., EncData<bool>EncDataStruct<1>). See Callback type generation.
The MXE encrypts outputs with nonce + 1. See Encryption overview for nonce handling.

Secondary use: shared key input optimization

When multiple inputs share the same encryption key, Enc<Shared, T> duplicates the key-derivation circuit for each input. Use EncData<T> with explicit key/nonce to avoid this:
#[instruction]
fn optimized_sum(
    key: ArcisX25519Pubkey,
    t_nonce: u128, t: EncData<u64>,
    u_nonce: u128, u: EncData<u64>,
) -> u64 {
    let t_val = t.to_arcis_with_pubkey_and_nonce(key, t_nonce);
    let u_val = u.to_arcis_with_pubkey_and_nonce(key, u_nonce);
    (t_val + u_val).reveal()
}
EncData<T> is an advanced optimization with security implications:
  • Nonce uniqueness: Each (key, nonce) pair must be unique. Reusing nonces compromises security.
  • Silent failures: Using the wrong key or nonce produces garbage data without error; MPC cannot add runtime validation since that would leak information.
For most use cases, use Enc<Shared, T> or Enc<Mxe, T>, which handle key management automatically.

Unsupported types

Arcis does not currently support HashMap, Vec, or String because these types have variable length. Constant-size byte strings, such as b"hello_world", are supported. The Enc type defines encrypted data input as Enc<Owner, T>, where Owner can be either Mxe or Shared. Owner determines which party can decrypt data of type T. See Input/output for encrypted input and output patterns.
Storage representation: All values are stored as 256-bit Curve25519 field elements. A u8 uses the same storage as a u128; integer type bounds are enforced at compile time, not by storage size. Use Pack<T> to compress multiple small values into fewer field elements for onchain efficiency.

What’s next?

Input/output

Working with Enc<Owner, T> for encrypted inputs and outputs.

Thinking in MPC

MPC constraints and the operation cost model.