Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 12 additions & 8 deletions host-contracts/contracts/FHEVMExecutor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,10 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
/// identical between `initializeFromEmptyProxy` and the `reinitializeVX` method
uint64 private constant REINITIALIZER_VERSION = 3;

/// Domain separator for hashing when building an output handle for a FHE computation
bytes8 private constant COMPUTATION_DOMAIN_SEPARATOR = "FHE_comp";
bytes8 private constant SEED_DOMAIN_SEPARATOR = "FHE_seed";

/// keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMExecutor")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant FHEVMExecutorStorageLocation =
0x4613e1771f6b755d243e536fb5a23c5b15e2826575fee921e8fe7a22a760c800;
Expand Down Expand Up @@ -671,7 +675,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {

/// @dev It must not cast to same type.
if (typeCt == toType) revert InvalidType();
result = keccak256(abi.encodePacked(Operators.cast, ct, toType, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, Operators.cast, ct, toType, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(result, toType);
hcuLimit.checkHCUForCast(toType, ct, result, msg.sender);
acl.allowTransient(result, msg.sender);
Expand All @@ -695,7 +699,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
(1 << uint8(FheType.Uint256));

if ((1 << uint8(toType)) & supportedTypes == 0) revert UnsupportedType();
result = keccak256(abi.encodePacked(Operators.trivialEncrypt, pt, toType, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, Operators.trivialEncrypt, pt, toType, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(result, toType);
hcuLimit.checkHCUForTrivialEncrypt(toType, result, msg.sender);
acl.allowTransient(result, msg.sender);
Expand Down Expand Up @@ -812,7 +816,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {

function _unaryOp(Operators op, bytes32 ct) internal virtual returns (bytes32 result) {
if (!acl.isAllowed(ct, msg.sender)) revert ACLNotAllowed(ct, msg.sender);
result = keccak256(abi.encodePacked(op, ct, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, op, ct, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
FheType typeCt = _typeOf(ct);
result = _appendMetadataToPrehandle(result, typeCt);
acl.allowTransient(result, msg.sender);
Expand All @@ -836,7 +840,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
FheType lhsType = _typeOf(lhs);
if (lhsType != rhsType) revert IncompatibleTypes();
}
result = keccak256(abi.encodePacked(op, lhs, rhs, scalar, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, op, lhs, rhs, scalar, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(result, resultType);
acl.allowTransient(result, msg.sender);
}
Expand All @@ -859,15 +863,15 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
if (lhsType != FheType.Bool) revert UnsupportedType();
if (middleType != rhsType) revert IncompatibleTypes();

result = keccak256(abi.encodePacked(op, lhs, middle, rhs, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, op, lhs, middle, rhs, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(result, middleType);
acl.allowTransient(result, msg.sender);
}

function _generateSeed() internal virtual returns (bytes16 seed) {
FHEVMExecutorStorage storage $ = _getFHEVMExecutorStorage();
seed = bytes16(
keccak256(abi.encodePacked($.counterRand, acl, block.chainid, blockhash(block.number - 1), block.timestamp))
keccak256(abi.encodePacked(SEED_DOMAIN_SEPARATOR, $.counterRand, acl, block.chainid, blockhash(block.number - 1), block.timestamp))
);
$.counterRand++;
}
Expand All @@ -883,7 +887,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {

/// @dev Unsupported erandom type.
if ((1 << uint8(randType)) & supportedTypes == 0) revert UnsupportedType();
result = keccak256(abi.encodePacked(Operators.fheRand, randType, seed));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, Operators.fheRand, randType, seed));
Comment thread
antoniupop marked this conversation as resolved.
result = _appendMetadataToPrehandle(result, randType);
hcuLimit.checkHCUForFheRand(randType, result, msg.sender);
acl.allowTransient(result, msg.sender);
Expand All @@ -904,7 +908,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
if ((1 << uint8(randType)) & supportedTypes == 0) revert UnsupportedType();
if (!_isPowerOfTwo(upperBound)) revert NotPowerOfTwo();
_checkBelowMaxBound(upperBound, randType);
result = keccak256(abi.encodePacked(Operators.fheRandBounded, upperBound, randType, seed));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, Operators.fheRandBounded, upperBound, randType, seed));
Comment thread
antoniupop marked this conversation as resolved.
result = _appendMetadataToPrehandle(result, randType);
hcuLimit.checkHCUForFheRandBounded(randType, result, msg.sender);
acl.allowTransient(result, msg.sender);
Expand Down
8 changes: 4 additions & 4 deletions host-contracts/rust_bindings/src/fhevm_executor.rs

Large diffs are not rendered by default.

22 changes: 12 additions & 10 deletions host-contracts/test/fhevmExecutor/fhevmExecutor.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
uint256 internal randomCounterForMockHandle;

uint8 internal constant HANDLE_VERSION = 0;
bytes8 internal constant COMPUTATION_DOMAIN_SEPARATOR = "FHE_comp";
bytes8 internal constant SEED_DOMAIN_SEPARATOR = "FHE_seed";
address internal constant owner = address(456);

MockACL internal acl;
Expand Down Expand Up @@ -312,7 +314,7 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
bytes32 handle,
FheType resultType
) internal view returns (bytes32 result) {
result = keccak256(abi.encodePacked(op, handle, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, op, handle, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(resultType, result, block.chainid, HANDLE_VERSION);
}

Expand All @@ -324,7 +326,7 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
FheType resultType
) internal view returns (bytes32 result) {
scalar = scalar & 0x01;
result = keccak256(abi.encodePacked(op, lhs, rhs, scalar, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, op, lhs, rhs, scalar, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(resultType, result, block.chainid, HANDLE_VERSION);
}

Expand All @@ -336,7 +338,7 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
FheType resultType
) internal view returns (bytes32 result) {
scalar = scalar & 0x01;
result = keccak256(abi.encodePacked(op, lhs, rhs, scalar, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, op, lhs, rhs, scalar, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(resultType, result, block.chainid, HANDLE_VERSION);
}

Expand All @@ -347,7 +349,7 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
bytes32 rhs,
FheType middleFheType
) internal view returns (bytes32 result) {
result = keccak256(abi.encodePacked(op, lhs, middle, rhs, acl, block.chainid));
result = keccak256(abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, op, lhs, middle, rhs, acl, block.chainid, blockhash(block.number - 1), block.timestamp));
result = _appendMetadataToPrehandle(middleFheType, result, block.chainid, HANDLE_VERSION);
}

Expand Down Expand Up @@ -1044,12 +1046,12 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
/// @dev The first argument is the counterRand, which should be 0 for the first call.
bytes16 expectedSeed = bytes16(
keccak256(
abi.encodePacked(uint256(i), acl, block.chainid, blockhash(block.number - 1), block.timestamp)
abi.encodePacked(SEED_DOMAIN_SEPARATOR, uint256(i), acl, block.chainid, blockhash(block.number - 1), block.timestamp)
)
);

bytes32 expectedResult = keccak256(
abi.encodePacked(FHEVMExecutor.Operators.fheRand, FheType(fheType), expectedSeed)
abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, FHEVMExecutor.Operators.fheRand, FheType(fheType), expectedSeed)
);

expectedResult = _appendMetadataToPrehandle(
Expand Down Expand Up @@ -1086,12 +1088,12 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
/// @dev The first argument is the counterRand, which should be 0 for the first call.
bytes16 expectedSeed = bytes16(
keccak256(
abi.encodePacked(uint256(i), acl, block.chainid, blockhash(block.number - 1), block.timestamp)
abi.encodePacked(SEED_DOMAIN_SEPARATOR, uint256(i), acl, block.chainid, blockhash(block.number - 1), block.timestamp)
)
);

bytes32 expectedResult = keccak256(
abi.encodePacked(FHEVMExecutor.Operators.fheRandBounded, upperBound, FheType(fheType), expectedSeed)
abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, FHEVMExecutor.Operators.fheRandBounded, upperBound, FheType(fheType), expectedSeed)
);

expectedResult = _appendMetadataToPrehandle(
Expand All @@ -1116,7 +1118,7 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
address sender = address(123);

bytes32 expectedResult = keccak256(
abi.encodePacked(FHEVMExecutor.Operators.trivialEncrypt, pt, FheType(fheType), acl, block.chainid)
abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, FHEVMExecutor.Operators.trivialEncrypt, pt, FheType(fheType), acl, block.chainid, blockhash(block.number - 1), block.timestamp)
);
expectedResult = _appendMetadataToPrehandle(FheType(fheType), expectedResult, block.chainid, HANDLE_VERSION);

Expand All @@ -1142,7 +1144,7 @@ contract FHEVMExecutorTest is SupportedTypesConstants, Test {
_approveHandleInACL(handle, sender);

bytes32 expectedResult = keccak256(
abi.encodePacked(FHEVMExecutor.Operators.cast, handle, FheType(fheOutputType), acl, block.chainid)
abi.encodePacked(COMPUTATION_DOMAIN_SEPARATOR, FHEVMExecutor.Operators.cast, handle, FheType(fheOutputType), acl, block.chainid, blockhash(block.number - 1), block.timestamp)
);

expectedResult = _appendMetadataToPrehandle(
Expand Down
Loading