User Decrypt Single Value

User-controlled decryption with mandatory two-step permissions. Demonstrates the pattern: allowThis() for contract storage/computation and allow() for user decryption, illustrating correct vs incorrect usage.

To run this example correctly, make sure the files are placed in the following directories:

  • .sol file → <your-project-root-dir>/contracts/

  • .ts file → <your-project-root-dir>/test/

This ensures Hardhat can compile and test your contracts as expected.

🔐 FHE API Reference (5 items)

Types: euint32

Functions:

  • FHE.add() - Homomorphic addition: result = a + b (overflow wraps)

  • FHE.allow() - Grants PERMANENT permission for address to decrypt/use value

  • FHE.allowThis() - Grants contract permission to operate on ciphertext

  • FHE.asEuint32() - Encrypts a plaintext uint32 value into euint32

// SPDX-License-Identifier: BSD-3-Clause-Clear
pragma solidity ^0.8.24;

import {FHE, euint32} from "@fhevm/solidity/lib/FHE.sol";
import {ZamaEthereumConfig} from "@fhevm/solidity/config/ZamaConfig.sol";

/**
 * @notice User-controlled decryption with mandatory two-step permissions.
 *         Demonstrates the pattern: allowThis() for contract storage/computation
 *         and allow() for user decryption, illustrating correct vs incorrect usage.
 *
 * @dev Both allowThis and allow are required for successful user decryption.
 */
contract UserDecryptSingleValue is ZamaEthereumConfig {
    euint32 private _trivialEuint32;

    /// @notice ✅ CORRECT: Proper permission pattern
    function initializeUint32(uint32 value) external {
        _trivialEuint32 = FHE.add(FHE.asEuint32(value), FHE.asEuint32(1));

        // 🔑 Why both needed?
        // - allowThis: Contract authorizes releasing the value
        // - allow: User can request decryption
        FHE.allowThis(_trivialEuint32);
        FHE.allow(_trivialEuint32, msg.sender);
    }

    /// @notice ❌ WRONG: Missing allowThis causes decryption to FAIL!
    /// @dev Common mistake - user gets permission but decryption still fails
    function initializeUint32Wrong(uint32 value) external {
        _trivialEuint32 = FHE.add(FHE.asEuint32(value), FHE.asEuint32(1));

        // ❌ Missing allowThis → user can't decrypt!
        // Why? Decryption needs contract authorization to release
        FHE.allow(_trivialEuint32, msg.sender);
    }

    function encryptedUint32() public view returns (euint32) {
        return _trivialEuint32;
    }
}

Last updated