Enclave is now The Interfold. Documentation is being updated.
Hello World

Hello World Tutorial

This tutorial walks you through building your first E3 program from scratch. You'll learn how each component works and how they interact to create a secure, encrypted computation.

Make sure to complete the Quick Start guide first to get familiar with the basic workflow before diving into this detailed tutorial.

What We're Building

We'll create a simple E3 program that:

  1. Accepts two encrypted numbers from users
  2. Computes their sum using Fully Homomorphic Encryption
  3. Returns the encrypted result without ever decrypting the inputs

Prerequisites

Before starting, ensure you have:

Step 1: Project Setup

Create a new E3 project:

enclave init hello-world-e3
cd hello-world-e3

Let's examine the generated project structure:

hello-world-e3/
├── program/           # FHE computation logic (Rust)
├── contracts/         # Smart contracts (Solidity)
├── client/           # Frontend application (React/TypeScript)
├── server/           # Coordination server (TypeScript)
├── enclave.config.yaml # Interfold configuration
└── README.md         # Project documentation

Step 2: Understanding the FHE Program

The heart of your E3 program is in ./program/src/lib.rs. Let's examine the default implementation:

use e3_fhe_params::decode_bfv_params_arc;
use e3_compute_provider::FHEInputs;
use fhe::bfv::Ciphertext;
use fhe_traits::{DeserializeParametrized, Serialize};
 
/// Implementation of the CiphertextProcessor function
pub fn fhe_processor(fhe_inputs: &FHEInputs) -> Vec<u8> {
    // Decode the FHE parameters
    let params = decode_bfv_params_arc(&fhe_inputs.params);
 
    // Start with zero (encrypted)
    let mut sum = Ciphertext::zero(&params);
 
    // Add each encrypted input to the sum
    for ciphertext_bytes in &fhe_inputs.ciphertexts {
        let ciphertext = Ciphertext::from_bytes(&ciphertext_bytes.0, &params).unwrap();
        sum += &ciphertext;  // Homomorphic addition
    }
 
    // Return the encrypted result
    sum.to_bytes()
}

Key Concepts:

  • FHEInputs: Contains encrypted data and parameters
  • Ciphertext: Encrypted values that can be computed on
  • Homomorphic operations: += works on encrypted data
  • No decryption: We never see the actual values

Step 3: Modifying the Computation

Let's create a more interesting computation. Replace the content of ./program/src/lib.rs:

use e3_fhe_params::decode_bfv_params_arc;
use e3_compute_provider::FHEInputs;
use fhe::bfv::Ciphertext;
use fhe_traits::{DeserializeParametrized, Serialize};
 
/// Compute: (a + b) * 2
pub fn fhe_processor(fhe_inputs: &FHEInputs) -> Vec<u8> {
    let params = decode_bfv_params_arc(&fhe_inputs.params);
 
    // Extract the two input ciphertexts
    if fhe_inputs.ciphertexts.len() != 2 {
        panic!("Expected exactly 2 inputs");
    }
 
    let a = Ciphertext::from_bytes(&fhe_inputs.ciphertexts[0].0, &params).unwrap();
    let b = Ciphertext::from_bytes(&fhe_inputs.ciphertexts[1].0, &params).unwrap();
 
    // Compute (a + b) * 2 homomorphically
    let sum = &a + &b;           // Add encrypted numbers
    let double = &sum + &sum;    // Multiply by 2 (via addition)
 
    double.to_bytes()
}

Step 4: Understanding the Configuration

The enclave.config.yaml file configures your development environment:

chains:
  - name: 'hardhat'
    rpc_url: 'ws://localhost:8545'
    contracts:
      e3_program: '0x9A676e781A523b5d0C0e43731313A708CB607508'
      # ... other contract addresses
 
nodes:
  cn1: # Ciphernode 1
    address: '0x70997970C51812dc3A010C7d01b50e0d17dc79C8'
    quic_port: 9201
    autonetkey: true
    autopassword: true
  # ... more nodes

Key Components:

  • Chains: Blockchain networks your E3 program uses
  • Contracts: Deployed smart contract addresses
  • Nodes: Ciphernodes that coordinate the E3 process

Step 5: Build and Test

Compile your modified program:

enclave program compile

Start the development environment:

pnpm dev:all

Step 6: Understanding the Client

The client application (in ./client/) handles:

  1. Encryption: User inputs → encrypted ciphertexts
  2. Submission: Publish encrypted data to the Interfold contract
  3. Result retrieval: Get the decrypted result from the Interfold contract

Step 7: Test Your Program

  1. Open http://localhost:3000 (opens in a new tab)
  2. Enter two numbers (e.g., 5 and 3)
  3. Submit the request
  4. Watch the result: (5 + 3) * 2 = 16

The computation happened entirely on encrypted data!

Step 8: Exploring Further

Now that you understand the basics, try these modifications:

Change the Computation

// Compute a² + b²
let a_squared = &a * &a;
let b_squared = &b * &b;
let result = &a_squared + &b_squared;

Add More Inputs

Modify your program to accept three or more encrypted inputs.

Update the UI

Customize the client application in ./client/src/ to match your computation.

Happy building with the Interfold! 🚀

Next Steps

Ready to build more complex E3 programs? Continue with:

  1. Writing the Secure Process - Advanced FHE programming
  2. Writing the E3 Program Contract - Smart contract integration
  3. Setting Up the Server - Custom coordination logic