Cypher Technical Documentation
  • Introduction
    • Overview
    • Key Features and Technical Advantages
    • Developer Focused Development
  • Technical Innovation
    • Fully Homomorphic Encryption EVM (fhEVM)
    • Layer 3 Architecture
    • Privacy-Preserving Data Management
    • Seamless Integration
    • Optimized for Privacy-Critical Applications
  • Cypher’s fhEVM Technology
    • What is fhEVM?
    • Architecture of fhEVM
    • Detailed Supported Operations in fhEVM
  • Deploying Smart Contracts on Cypher Testnet
    • Configuration and Deployment
    • Obtaining Testnet Tokens
  • Operations in a fhEVM Framework
    • Concepts
    • Random
    • Secret Store and Access Control in Encrypted Smart Contracts
    • Using fhevmjs for Encrypted Smart Contract Development
  • Tokenomics V2
    • $DEAI Token
    • Token Utility
    • Token Distribution
  • Cypher Layer 3 Tech Integration
  • Glossary
Powered by GitBook
On this page
  • Shift Operations in TFHE
  • Supported Operators for Encrypted Integers
  • Comparison Operations
  • Error Handling in Encrypted Smart Contracts
  • Random Number Generation
  • Encrypted Inputs
  • Access Control List (ACL) System
  1. Operations in a fhEVM Framework

Random

Shift Operations in TFHE

The TFHE.shr and TFHE.shl shift operations work with an encrypted integer type (euintX) as the first operand and either uint8 or euint8 as the second operand. The second operand is computed modulo the bit width of the first operand.

Example:

TFHE.shr(euint64 x, 70);

This results in:

TFHE.shr(euint64 x, 6); // Because 70 % 64 = 6

This differs from standard Solidity shifts where, for instance, a right shift (>>) could result in a null value if the operand exceeds the bit width.

Supported Operators for Encrypted Integers

TFHE supports overloaded operators like +, -, *, &, etc., for encrypted integers. These operators invoke versions without overflow checks by default.

Comparison Operations

In Fully Homomorphic Encryption (FHE), comparison operations yield encrypted boolean results of type ebool. As ebool maintains confidentiality, it cannot be directly used in standard boolean operations.

To address this, the fhEVM framework provides the select function, which is similar to a ternary operator. It enables conditional assignments based on ebool values.

Example:

function bid(einput encryptedValue, bytes calldata inputProof) public onlyBeforeEnd {
    euint64 bid = TFHE.asEuint64(encryptedValue, inputProof);
    ebool isAbove = TFHE.lt(highestBid, bid);
    highestBid = TFHE.select(isAbove, bid, highestBid);
    TFHE.allow(highestBid, address(this));
}

Explanation:

  1. Decryption: The encryptedValue is decrypted into an euint64 type using TFHE.asEuint64, preserving confidentiality.

  2. Comparison: The TFHE.lt function compares the current highestBid with the new bid, producing an ebool that indicates if the new bid is higher.

  3. Conditional Assignment: The TFHE.select function updates highestBid based on the isAbove condition.

Error Handling in Encrypted Smart Contracts

Error handling requires custom strategies, as failed conditions in encrypted contracts do not automatically revert transactions. Instead, an error handler records the latest error information for each wallet.

Example:

struct LastError {
    euint8 error;
    uint timestamp;
}

euint8 internal NO_ERROR;
euint8 internal NOT_ENOUGH_FUND;

constructor() {
    NO_ERROR = TFHE.asEuint8(0);
    NOT_ENOUGH_FUND = TFHE.asEuint8(1);
}

function setLastError(euint8 error, address addr) private {
    _lastErrors[addr] = LastError(error, block.timestamp);
    emit ErrorChanged(addr);
}

function _transfer(address from, address to, euint32 amount) internal {
    ebool canTransfer = TFHE.le(amount, balances[from]);
    euint64 transferValue = TFHE.select(canTransfer, amount, TFHE.asEuint64(0));
    setLastError(TFHE.select(canTransfer, NO_ERROR, NOT_ENOUGH_FUND), msg.sender);
    balances[to] = TFHE.add(balances[to], transferValue);
    TFHE.allow(balances[to], address(this));
    TFHE.allow(balances[to], to);
    balances[from] = TFHE.sub(balances[from], transferValue);
    TFHE.allow(balances[from], address(this));
    TFHE.allow(balances[from], from);
}

Random Number Generation

TFHE enables fully on-chain random number generation with the following functions:

euint8 r8 = TFHE.randEuint8();
euint16 r16 = TFHE.randEuint16();
euint32 r32 = TFHE.randEuint32();
euint64 r64 = TFHE.randEuint64();

Encrypted Inputs

Encrypted inputs are fundamental to fhEVM, allowing users to push encrypted data onto the blockchain securely. Users must provide proof of knowledge of the plaintext to prevent ciphertext reuse.

Function Example:

function myExample(
    address account,
    einput param1,
    uint id,
    einput param2,
    einput param3,
    bool isAllowed,
    bytes calldata inputProof
) public {
    // Implementation
}

Client-Side Implementation:

const instance = await createInstance({ networkUrl: "http://localhost:8545" });

// Create encrypted inputs
const input = instance.createEncryptedInput(contractAddress, userAddress);
const inputs = input.add64(64).addBool(true).add8(4).encrypt(); // Encrypt the three parameters

// Call the smart contract function with encrypted parameters
contract.myExample(
    "0xa5e1defb98EFe38EBb2D958CEe052410247F4c80", // account address
    inputs.handles[0],                          // param1
    32,                                         // id
    inputs.handles[1],                          // param2
    inputs.handles[2],                          // param3
    true,                                       // isAllowed
    inputs.inputProof                           // inputProof
);

Access Control List (ACL) System

fhEVM includes an ACL system to define which addresses can manipulate ciphertexts. This feature ensures that unauthorized addresses cannot access or modify the contents of any ciphertext. Two types of allowances are supported:

Permanent Allowance:

TFHE.allow(ciphertext, address);
  • Grants permanent access to a ciphertext for a specific address on the blockchain.

  • The ciphertext can be used by the authorized address at any time.

  • The ACL is stored in a dedicated contract.

Temporary Allowance:

TFHE.allowTransient(ciphertext, address);
  • Grants temporary access to a ciphertext for the duration of a transaction.

  • The ACL is stored in transient storage, saving gas costs.

  • Particularly useful when calling an external function using a ciphertext as a parameter.

Example: Function Calling Another Function

contract SecretGiver {
    SecretStore public secretStore;

    constructor() {
        secretStore = new SecretStore();
    }

    function giveMySecret() public {
        euint16 mySecret = TFHE.asEuint16(42);
        TFHE.allowTransient(mySecret, address(secretStore));
        secretStore.storeSecret(mySecret);
    }
}
PreviousConceptsNextSecret Store and Access Control in Encrypted Smart Contracts

Last updated 5 months ago