07 — FHE Basics

Fully Homomorphic Encryption (FHE) lets you perform arithmetic on ciphertext — computations happen on encrypted data, and only the key holder can decrypt the result.

Covenant wraps FHE operations in the encrypted<T> type family.

Declaring encrypted fields

contract SecretVoting {
  field tally: encrypted<u256> = fhe_zero()
}

fhe_zero() initialises the accumulator to an encryption of 0.

Supported operations

FunctionDescription
fhe_add(a, b)Homomorphic addition
fhe_mul(a, b)Homomorphic multiplication
fhe_sub(a, b)Homomorphic subtraction
fhe_eq(a, b)Equality test (returns encrypted<Bool>)
fhe_lt(a, b)Less-than comparison
fhe_decrypt(c, key)Decrypt with a key — emits proof of correct decryption
fhe_reencrypt(c, pubkey)Re-encrypt under a different public key

Example: private vote accumulator

contract PrivateVoting {
  field tally: encrypted<u256> = fhe_zero()
  field voted:  Map<Address, Bool>

  error AlreadyVoted

  action cast_vote(encrypted_vote: encrypted<u256>) {
    require(!self.voted[msg.sender], AlreadyVoted);
    self.voted[msg.sender] = true;
    // Add ciphertext directly — no decryption needed
    self.tally = fhe_add(self.tally, encrypted_vote);
  }

  // Owner can decrypt the final tally
  action reveal_tally() -> u256 {
    only(owner);
    return fhe_decrypt(self.tally, fhe_owner_key());
  }
}

Scheme selection

Covenant is scheme-agnostic at the source level. Configure the FHE backend in covenant.toml:

[fhe]
scheme = "tfhe"   # options: tfhe | bgv | ckks
params = "default_128"

The compiler emits precompile calls to the scheme-specific EVM precompile registered at the target chain’s genesis.

Gas model

FHE operations are expensive — each fhe_add costs ~2 M gas and fhe_mul ~40 M gas on a standard EVM. On Aster Chain (ID 1996), the privacy precompiles are subsidised by the validator set and cost 10–100× less.

Tip: batch FHE operations in a single action to amortise proof-verification overhead.