@@ -140,6 +140,10 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
140140 /// identical between `initializeFromEmptyProxy` and the `reinitializeVX` method
141141 uint64 private constant REINITIALIZER_VERSION = 3 ;
142142
143+ /// Domain separator for hashing when building an output handle for a FHE computation
144+ bytes8 private constant COMPUTATION_DOMAIN_SEPARATOR = "FHE_comp " ;
145+ bytes8 private constant SEED_DOMAIN_SEPARATOR = "FHE_seed " ;
146+
143147 /// keccak256(abi.encode(uint256(keccak256("fhevm.storage.FHEVMExecutor")) - 1)) & ~bytes32(uint256(0xff))
144148 bytes32 private constant FHEVMExecutorStorageLocation =
145149 0x4613e1771f6b755d243e536fb5a23c5b15e2826575fee921e8fe7a22a760c800 ;
@@ -671,7 +675,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
671675
672676 /// @dev It must not cast to same type.
673677 if (typeCt == toType) revert InvalidType ();
674- result = keccak256 (abi.encodePacked (Operators.cast, ct, toType, acl, block .chainid ));
678+ result = keccak256 (abi.encodePacked (COMPUTATION_DOMAIN_SEPARATOR, Operators.cast, ct, toType, acl, block .chainid , blockhash ( block . number - 1 ), block . timestamp ));
675679 result = _appendMetadataToPrehandle (result, toType);
676680 hcuLimit.checkHCUForCast (toType, ct, result, msg .sender );
677681 acl.allowTransient (result, msg .sender );
@@ -695,7 +699,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
695699 (1 << uint8 (FheType.Uint256));
696700
697701 if ((1 << uint8 (toType)) & supportedTypes == 0 ) revert UnsupportedType ();
698- result = keccak256 (abi.encodePacked (Operators.trivialEncrypt, pt, toType, acl, block .chainid ));
702+ result = keccak256 (abi.encodePacked (COMPUTATION_DOMAIN_SEPARATOR, Operators.trivialEncrypt, pt, toType, acl, block .chainid , blockhash ( block . number - 1 ), block . timestamp ));
699703 result = _appendMetadataToPrehandle (result, toType);
700704 hcuLimit.checkHCUForTrivialEncrypt (toType, result, msg .sender );
701705 acl.allowTransient (result, msg .sender );
@@ -812,7 +816,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
812816
813817 function _unaryOp (Operators op , bytes32 ct ) internal virtual returns (bytes32 result ) {
814818 if (! acl.isAllowed (ct, msg .sender )) revert ACLNotAllowed (ct, msg .sender );
815- result = keccak256 (abi.encodePacked (op, ct, acl, block .chainid ));
819+ result = keccak256 (abi.encodePacked (COMPUTATION_DOMAIN_SEPARATOR, op, ct, acl, block .chainid , blockhash ( block . number - 1 ), block . timestamp ));
816820 FheType typeCt = _typeOf (ct);
817821 result = _appendMetadataToPrehandle (result, typeCt);
818822 acl.allowTransient (result, msg .sender );
@@ -836,7 +840,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
836840 FheType lhsType = _typeOf (lhs);
837841 if (lhsType != rhsType) revert IncompatibleTypes ();
838842 }
839- result = keccak256 (abi.encodePacked (op, lhs, rhs, scalar, acl, block .chainid ));
843+ result = keccak256 (abi.encodePacked (COMPUTATION_DOMAIN_SEPARATOR, op, lhs, rhs, scalar, acl, block .chainid , blockhash ( block . number - 1 ), block . timestamp ));
840844 result = _appendMetadataToPrehandle (result, resultType);
841845 acl.allowTransient (result, msg .sender );
842846 }
@@ -859,15 +863,15 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
859863 if (lhsType != FheType.Bool) revert UnsupportedType ();
860864 if (middleType != rhsType) revert IncompatibleTypes ();
861865
862- result = keccak256 (abi.encodePacked (op, lhs, middle, rhs, acl, block .chainid ));
866+ result = keccak256 (abi.encodePacked (COMPUTATION_DOMAIN_SEPARATOR, op, lhs, middle, rhs, acl, block .chainid , blockhash ( block . number - 1 ), block . timestamp ));
863867 result = _appendMetadataToPrehandle (result, middleType);
864868 acl.allowTransient (result, msg .sender );
865869 }
866870
867871 function _generateSeed () internal virtual returns (bytes16 seed ) {
868872 FHEVMExecutorStorage storage $ = _getFHEVMExecutorStorage ();
869873 seed = bytes16 (
870- keccak256 (abi.encodePacked ($.counterRand, acl, block .chainid , blockhash (block .number - 1 ), block .timestamp ))
874+ keccak256 (abi.encodePacked (SEED_DOMAIN_SEPARATOR, $.counterRand, acl, block .chainid , blockhash (block .number - 1 ), block .timestamp ))
871875 );
872876 $.counterRand++ ;
873877 }
@@ -883,7 +887,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
883887
884888 /// @dev Unsupported erandom type.
885889 if ((1 << uint8 (randType)) & supportedTypes == 0 ) revert UnsupportedType ();
886- result = keccak256 (abi.encodePacked (Operators.fheRand, randType, seed));
890+ result = keccak256 (abi.encodePacked (COMPUTATION_DOMAIN_SEPARATOR, Operators.fheRand, randType, seed));
887891 result = _appendMetadataToPrehandle (result, randType);
888892 hcuLimit.checkHCUForFheRand (randType, result, msg .sender );
889893 acl.allowTransient (result, msg .sender );
@@ -904,7 +908,7 @@ contract FHEVMExecutor is UUPSUpgradeableEmptyProxy, FHEEvents, ACLOwnable {
904908 if ((1 << uint8 (randType)) & supportedTypes == 0 ) revert UnsupportedType ();
905909 if (! _isPowerOfTwo (upperBound)) revert NotPowerOfTwo ();
906910 _checkBelowMaxBound (upperBound, randType);
907- result = keccak256 (abi.encodePacked (Operators.fheRandBounded, upperBound, randType, seed));
911+ result = keccak256 (abi.encodePacked (COMPUTATION_DOMAIN_SEPARATOR, Operators.fheRandBounded, upperBound, randType, seed));
908912 result = _appendMetadataToPrehandle (result, randType);
909913 hcuLimit.checkHCUForFheRandBounded (randType, result, msg .sender );
910914 acl.allowTransient (result, msg .sender );
0 commit comments