mirror of
https://github.com/zama-ai/fhevm-solidity.git
synced 2026-05-09 03:00:27 -04:00
* feat: use latest core contracts, updated lib API, renamed to fhevm and fhe chore: add dummy addresses for CI test: add tests for makePubliclyDecryptable method * chore: update package-lock.json for linux * chore: update package-lock.json * fix: solidity comments (#746) * chore: update oracle version * chore: update fhevm core-contracts version * feat: update fhevm sdk and mocked userDecrypt * chore: fix coverage
823 lines
30 KiB
Solidity
823 lines
30 KiB
Solidity
// SPDX-License-Identifier: BSD-3-Clause-Clear
|
|
pragma solidity ^0.8.24;
|
|
|
|
import {FheType} from "./FheType.sol";
|
|
|
|
/**
|
|
* @title FHEVMConfigStruct
|
|
* @notice This struct contains all addresses of core contracts, which are needed in a typical dApp.
|
|
*/
|
|
struct FHEVMConfigStruct {
|
|
address ACLAddress;
|
|
address FHEVMExecutorAddress;
|
|
address KMSVerifierAddress;
|
|
address InputVerifierAddress;
|
|
}
|
|
|
|
/**
|
|
* @title DecryptionRequestsStruct
|
|
* @notice This struct contains the address of the decryption oracle contract,
|
|
* the internal counter for requestIDs generated by the dapp,
|
|
* and the mapping from internal requestIDs to list of handles requested for decryption.
|
|
*/
|
|
struct DecryptionRequestsStruct {
|
|
address DecryptionOracleAddress;
|
|
uint256 counterRequest;
|
|
mapping(uint256 => bytes32[]) requestedHandles;
|
|
}
|
|
|
|
/**
|
|
* @title IFHEVMExecutor
|
|
* @notice This interface contains all functions to conduct FHE operations.
|
|
*/
|
|
interface IFHEVMExecutor {
|
|
/**
|
|
* @notice Computes fheAdd operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheAdd(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheSub operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheSub(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheMul operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheMul(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheDiv operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheDiv(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheRem operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheRem(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheBitAnd operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheBitAnd(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheBitOr operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheBitOr(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheBitXor operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheBitXor(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheShl operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheShl(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheShr operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheShr(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheRotl operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheRotl(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheRotr operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheRotr(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheEq operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheEq(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheNe operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheNe(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheGe operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheGe(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheGt operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheGt(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheLe operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheLe(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheLt operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheLt(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheMin operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheMin(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheMax operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheMax(bytes32 lhs, bytes32 rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheNeg operation.
|
|
* @param ct Ct
|
|
* @return result Result.
|
|
*/
|
|
function fheNeg(bytes32 ct) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes fheNot operation.
|
|
* @param ct Ct
|
|
* @return result Result.
|
|
*/
|
|
function fheNot(bytes32 ct) external returns (bytes32 result);
|
|
/**
|
|
* @notice Verifies the ciphertext.
|
|
* @param inputHandle Input handle.
|
|
* @param callerAddress Address of the caller.
|
|
* @param inputProof Input proof.
|
|
* @param inputType Input type.
|
|
* @return result Result.
|
|
*/
|
|
function verifyCiphertext(
|
|
bytes32 inputHandle,
|
|
address callerAddress,
|
|
bytes memory inputProof,
|
|
FheType inputType
|
|
) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Performs the casting to a target type.
|
|
* @param ct Value to cast.
|
|
* @param toType Target type.
|
|
* @return result Result value of the target type.
|
|
*/
|
|
function cast(bytes32 ct, FheType toType) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Does trivial encryption.
|
|
* @param ct Value to encrypt.
|
|
* @param toType Target type.
|
|
* @return result Result value of the target type.
|
|
*/
|
|
function trivialEncrypt(uint256 ct, FheType toType) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Does trivial encryption.
|
|
* @param ct Value to encrypt.
|
|
* @param toType Target type.
|
|
* @return result Result value of the target type.
|
|
*/
|
|
function trivialEncrypt(bytes memory ct, FheType toType) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes FHEEq operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheEq(bytes32 lhs, bytes memory rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes FHENe operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalarByte Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function fheNe(bytes32 lhs, bytes memory rhs, bytes1 scalarByte) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes FHEIfThenElse operation.
|
|
* @param control Control value.
|
|
* @param ifTrue If true.
|
|
* @param ifFalse If false.
|
|
* @return result Result.
|
|
*/
|
|
function fheIfThenElse(bytes32 control, bytes32 ifTrue, bytes32 ifFalse) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes FHERand operation.
|
|
* @param randType Type for the random result.
|
|
* @return result Result.
|
|
*/
|
|
function fheRand(FheType randType) external returns (bytes32 result);
|
|
|
|
/**
|
|
* @notice Computes FHERandBounded operation.
|
|
* @param upperBound Upper bound value.
|
|
* @param randType Type for the random result.
|
|
* @return result Result.
|
|
*/
|
|
function fheRandBounded(uint256 upperBound, FheType randType) external returns (bytes32 result);
|
|
}
|
|
|
|
/**
|
|
* @title IACL.
|
|
* @notice This interface contains all functions that are used to conduct operations
|
|
* with the ACL contract.
|
|
*/
|
|
interface IACL {
|
|
/**
|
|
* @notice Allows the use of handle by address account for this transaction.
|
|
* @dev The caller must be allowed to use handle for allowTransient() to succeed.
|
|
* If not, allowTransient() reverts.
|
|
* The Coprocessor contract can always allowTransient(), contrarily to allow().
|
|
* @param ciphertext Ciphertext.
|
|
* @param account Address of the account.
|
|
*/
|
|
function allowTransient(bytes32 ciphertext, address account) external;
|
|
|
|
/**
|
|
* @notice Allows the use of handle for the address account.
|
|
* @dev The caller must be allowed to use handle for allow() to succeed. If not, allow() reverts.
|
|
* @param handle Handle.
|
|
* @param account Address of the account.
|
|
*/
|
|
function allow(bytes32 handle, address account) external;
|
|
|
|
/**
|
|
* @dev This function removes the transient allowances, which could be useful for integration with
|
|
* Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
|
|
*/
|
|
function cleanTransientStorage() external;
|
|
|
|
/**
|
|
* @notice Returns whether the account is allowed to use the handle, either due to
|
|
* allowTransient() or allow().
|
|
* @param handle Handle.
|
|
* @param account Address of the account.
|
|
* @return isAllowed Whether the account can access the handle.
|
|
*/
|
|
function isAllowed(bytes32 handle, address account) external view returns (bool);
|
|
|
|
/**
|
|
* @notice Allows a list of handles to be decrypted.
|
|
* @param handlesList List of handles.
|
|
*/
|
|
function allowForDecryption(bytes32[] memory handlesList) external;
|
|
|
|
/**
|
|
* @notice Returns wether a handle is allowed to be publicly decrypted.
|
|
* @param handle Handle.
|
|
* @return isDecryptable Whether the handle can be publicly decrypted.
|
|
*/
|
|
function isAllowedForDecryption(bytes32 handle) external view returns (bool);
|
|
}
|
|
|
|
/**
|
|
* @title IInputVerifier
|
|
* @notice This interface contains the only function required from InputVerifier.
|
|
*/
|
|
interface IInputVerifier {
|
|
/**
|
|
* @dev This function removes the transient allowances, which could be useful for integration with
|
|
* Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
|
|
*/
|
|
function cleanTransientStorage() external;
|
|
}
|
|
|
|
/**
|
|
* @title Impl
|
|
* @notice This library is the core implementation for computing FHE operations (e.g. add, sub, xor).
|
|
*/
|
|
library Impl {
|
|
/// keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMConfig")) - 1)) & ~bytes32(uint256(0xff))
|
|
bytes32 private constant FHEVMConfigLocation = 0xed8d60e34876f751cc8b014c560745351147d9de11b9347c854e881b128ea600;
|
|
|
|
/// keccak256(abi.encode(uint256(keccak256("fhevm.storage.DecryptionRequests")) - 1)) & ~bytes32(uint256(0xff))
|
|
bytes32 private constant DecryptionRequestsStorageLocation =
|
|
0x5ea69329017273582817d320489fbd94f775580e90c092699ca6f3d12fdf7d00;
|
|
|
|
/**
|
|
* @dev Returns the FHEVM config.
|
|
*/
|
|
function getFHEVMConfig() internal pure returns (FHEVMConfigStruct storage $) {
|
|
assembly {
|
|
$.slot := FHEVMConfigLocation
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @dev Returns the DecryptionRequestsStruct storage struct.
|
|
*/
|
|
function getDecryptionRequests() internal pure returns (DecryptionRequestsStruct storage $) {
|
|
assembly {
|
|
$.slot := DecryptionRequestsStorageLocation
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @notice Sets the coprocessor addresses.
|
|
* @param fhevmConfig FHEVM config struct that contains contract addresses.
|
|
*/
|
|
function setCoprocessor(FHEVMConfigStruct memory fhevmConfig) internal {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
$.ACLAddress = fhevmConfig.ACLAddress;
|
|
$.FHEVMExecutorAddress = fhevmConfig.FHEVMExecutorAddress;
|
|
$.KMSVerifierAddress = fhevmConfig.KMSVerifierAddress;
|
|
$.InputVerifierAddress = fhevmConfig.InputVerifierAddress;
|
|
}
|
|
|
|
/**
|
|
* @notice Sets the decryption oracle address.
|
|
* @param decryptionOracle The decryption oracle address.
|
|
*/
|
|
function setDecryptionOracle(address decryptionOracle) internal {
|
|
DecryptionRequestsStruct storage $ = getDecryptionRequests();
|
|
$.DecryptionOracleAddress = decryptionOracle;
|
|
}
|
|
|
|
function add(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheAdd(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function sub(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheSub(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function mul(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheMul(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function div(bytes32 lhs, bytes32 rhs) internal returns (bytes32 result) {
|
|
bytes1 scalarByte = 0x01;
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheDiv(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function rem(bytes32 lhs, bytes32 rhs) internal returns (bytes32 result) {
|
|
bytes1 scalarByte = 0x01;
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheRem(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function and(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheBitAnd(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function or(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheBitOr(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function xor(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheBitXor(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function shl(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheShl(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function shr(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheShr(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function rotl(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheRotl(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function rotr(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheRotr(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function eq(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheEq(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function ne(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheNe(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function ge(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheGe(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function gt(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheGt(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function le(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheLe(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function lt(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheLt(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function min(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheMin(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function max(bytes32 lhs, bytes32 rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheMax(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function neg(bytes32 ct) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheNeg(ct);
|
|
}
|
|
|
|
function not(bytes32 ct) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheNot(ct);
|
|
}
|
|
|
|
/**
|
|
* @dev If 'control's value is 'true', the result has the same value as 'ifTrue'.
|
|
* If 'control's value is 'false', the result has the same value as 'ifFalse'.
|
|
*/
|
|
function select(bytes32 control, bytes32 ifTrue, bytes32 ifFalse) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheIfThenElse(control, ifTrue, ifFalse);
|
|
}
|
|
|
|
/**
|
|
* @notice Verifies the ciphertext (FHEVMExecutor) and allows transient (ACL).
|
|
* @param inputHandle Input handle.
|
|
* @param inputProof Input proof.
|
|
* @param toType Input type.
|
|
* @return result Result.
|
|
*/
|
|
function verify(bytes32 inputHandle, bytes memory inputProof, FheType toType) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).verifyCiphertext(inputHandle, msg.sender, inputProof, toType);
|
|
IACL($.ACLAddress).allowTransient(result, msg.sender);
|
|
}
|
|
|
|
/**
|
|
* @notice Performs the casting to a target type.
|
|
* @param ciphertext Ciphertext to cast.
|
|
* @param toType Target type.
|
|
* @return result Result value of the target type.
|
|
*/
|
|
function cast(bytes32 ciphertext, FheType toType) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).cast(ciphertext, toType);
|
|
}
|
|
|
|
/**
|
|
* @notice Does trivial encryption.
|
|
* @param value Value to encrypt.
|
|
* @param toType Target type.
|
|
* @return result Result value of the target type.
|
|
*/
|
|
function trivialEncrypt(uint256 value, FheType toType) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).trivialEncrypt(value, toType);
|
|
}
|
|
|
|
/**
|
|
* @notice Does trivial encryption.
|
|
* @param value Value to encrypt.
|
|
* @param toType Target type.
|
|
* @return result Result value of the target type.
|
|
*/
|
|
function trivialEncrypt(bytes memory value, FheType toType) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).trivialEncrypt(value, toType);
|
|
}
|
|
|
|
/**
|
|
* @notice Computes FHEEq operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalar Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function eq(bytes32 lhs, bytes memory rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheEq(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
/**
|
|
* @notice Computes FHENe operation.
|
|
* @param lhs LHS.
|
|
* @param rhs RHS.
|
|
* @param scalar Scalar byte.
|
|
* @return result Result.
|
|
*/
|
|
function ne(bytes32 lhs, bytes memory rhs, bool scalar) internal returns (bytes32 result) {
|
|
bytes1 scalarByte;
|
|
if (scalar) {
|
|
scalarByte = 0x01;
|
|
} else {
|
|
scalarByte = 0x00;
|
|
}
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheNe(lhs, rhs, scalarByte);
|
|
}
|
|
|
|
function rand(FheType randType) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheRand(randType);
|
|
}
|
|
|
|
function randBounded(uint256 upperBound, FheType randType) internal returns (bytes32 result) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
result = IFHEVMExecutor($.FHEVMExecutorAddress).fheRandBounded(upperBound, randType);
|
|
}
|
|
|
|
/**
|
|
* @notice Allows the use of handle by address account for this transaction.
|
|
* @dev The caller must be allowed to use handle for allowTransient() to succeed.
|
|
* If not, allowTransient() reverts.
|
|
* The Coprocessor contract can always allowTransient(), contrarily to allow().
|
|
* @param handle Handle.
|
|
* @param account Address of the account.
|
|
*/
|
|
function allowTransient(bytes32 handle, address account) internal {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
IACL($.ACLAddress).allowTransient(handle, account);
|
|
}
|
|
|
|
/**
|
|
* @notice Allows the use of handle for the address account.
|
|
* @dev The caller must be allowed to use handle for allow() to succeed. If not, allow() reverts.
|
|
* @param handle Handle.
|
|
* @param account Address of the account.
|
|
*/
|
|
function allow(bytes32 handle, address account) internal {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
IACL($.ACLAddress).allow(handle, account);
|
|
}
|
|
|
|
/**
|
|
* @notice Allows the handle to be publicly decryptable.
|
|
* @dev The caller must be allowed to use handle for makePubliclyDecryptable() to succeed.
|
|
* If not, makePubliclyDecryptable() reverts.
|
|
* @param handle Handle.
|
|
*/
|
|
function makePubliclyDecryptable(bytes32 handle) internal {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
bytes32[] memory handleArray = new bytes32[](1);
|
|
handleArray[0] = handle;
|
|
IACL($.ACLAddress).allowForDecryption(handleArray);
|
|
}
|
|
|
|
/**
|
|
* @dev This function removes the transient allowances in the ACL, which could be useful for integration
|
|
* with Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
|
|
*/
|
|
function cleanTransientStorageACL() internal {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
IACL($.ACLAddress).cleanTransientStorage();
|
|
}
|
|
|
|
/**
|
|
* @dev This function removes the transient proofs in the InputVerifier, which could be useful for integration
|
|
* with Account Abstraction when bundling several UserOps calling the FHEVMExecutor Coprocessor.
|
|
*/
|
|
function cleanTransientStorageInputVerifier() internal {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
IInputVerifier($.InputVerifierAddress).cleanTransientStorage();
|
|
}
|
|
|
|
/**
|
|
* @notice Returns whether the account is allowed to use the handle, either due to
|
|
* allowTransient() or allow().
|
|
* @param handle Handle.
|
|
* @param account Address of the account.
|
|
* @return isAllowed Whether the account can access the handle.
|
|
*/
|
|
function isAllowed(bytes32 handle, address account) internal view returns (bool) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
return IACL($.ACLAddress).isAllowed(handle, account);
|
|
}
|
|
|
|
/**
|
|
* @notice Returns whether the handle is allowed to be publicly decrypted.
|
|
* @param handle Handle.
|
|
* @return isAllowed Whether the handle can be publicly decrypted.
|
|
*/
|
|
function isPubliclyDecryptable(bytes32 handle) internal view returns (bool) {
|
|
FHEVMConfigStruct storage $ = getFHEVMConfig();
|
|
return IACL($.ACLAddress).isAllowedForDecryption(handle);
|
|
}
|
|
}
|