diff --git a/docs/getting_started/FheLib.md b/docs/getting_started/FheLib.md
index c566824..101af53 100644
--- a/docs/getting_started/FheLib.md
+++ b/docs/getting_started/FheLib.md
@@ -1,15 +1,14 @@
 # FheLib
 
-`FheLib` is a library implemented inside fhevm-go. It offers FHE-related functionalities such as homomorphic operations, decryption/reencryption requests and so on. FheLib is exposed as a single `precompiled` contract (or a `precompile` for short) that is integrated into the underlying blockchain.
+`FheLib` is a library implemented inside fhevm-go. It offers FHE-related functionalities such as homomorphic operations, input verification and so on. FheLib is exposed as a single `precompiled` contract (or a `precompile` for short) that is integrated into the underlying blockchain.
 
 FheLib functions can be called by calling the FheLib precompile with a respective EVM function selector.
 
 This page describes the required inputs, behaviours and outputs of some of these functions.
 
-## GetCiphertext Function (selector: e4b808cb)
+## GetCiphertext Function (selector: ff627e77)
 
-The `GetCiphertext` function returns a serialized TFHE ciphertext from protected storage given:
- * contract address where the ciphertext is stored at
+The `GetCiphertext` function returns a serialized TFHE ciphertext given:
  * the ebool/e(u)int value (also called a handle) for which the ciphertext is requested
 
 GetCiphertext only works via the `eth_call` RPC.
@@ -23,30 +22,20 @@ import json
 # This is the address of the FheLib precompile. This value is hardcoded per blockchain.
 fhe_lib_precompile_address = "0x000000000000000000000000000000000000005d"
 
-# The contract address where the ciphertext is stored at.
-contract_address = "ACD7Be4EBF68Bf2A5b6eB0CaFb15460C169BC459"
-# 12 bytes of 0s for padding the contract address.
-address_zero_padding = "000000000000000000000000"
-
 # The ebool/e(u)int value for which the ciphertext is requested.
 handle = "f038cdc8bf630e239f143abeb039b91ec82ec17a8460582e7a409fa551030c06"
 
 # The function selector of GetCiphertext.
-get_ciphertext_selector = "e4b808cb"
+get_ciphertext_selector = "ff627e77"
 
-# Call the FheLib precompile with `data` being the concatenation of:
-#  - getCiphertext function selector;
-#  - 12 bytes of 0s to padd the contract address;
-#  - contract address;
-#  - the handle to the ciphertext.
+# Call the FheLib precompile with `data` being the handle to the ciphertext.
 payload = {
     "jsonrpc": "2.0",
     "method": "eth_call",
     "params": [
         {
             "to": fhe_lib_precompile_address,
-            "data": "0x" + get_ciphertext_selector + address_zero_padding +
-                    contract_address + handle
+            "data": "0x" + handle
         },
         "latest"
     ],
@@ -60,4 +49,4 @@ resp = json.loads(con.getresponse().read())
 
 # Remove leading "0x" and decode hex to get a byte buffer with the ciphertext.
 ciphertext = bytes.fromhex(resp["result"][2:])
-```
\ No newline at end of file
+```
diff --git a/docs/getting_started/Integration.md b/docs/getting_started/Integration.md
index 9cb3992..c655820 100644
--- a/docs/getting_started/Integration.md
+++ b/docs/getting_started/Integration.md
@@ -126,7 +126,7 @@ func NewEVM(blockCtx BlockContext, txCtx TxContext, statedb StateDB, chainConfig
 
 - Initialize `isGasEstimation` using `config.IsGasEstimation`
 - Initialize `isEthCall` using `config.IsEthCall`
-- Initialize `fhevmEnvironment` with `FhevmImplementation{interpreter: nil, logger: &fhevm.DefaultLogger{}, data: fhevm.NewFhevmData(), params: fhevm.DefaultFhevmParams()}`
+- Initialize `fhevmEnvironment` with `FhevmImplementation{interpreter: nil, logger: fhevm.NewDefaultLogger(), data: fhevm.NewFhevmData(), params: fhevm.DefaultFhevmParams()}`
 - After initializing `evm.interpreter` make sure to point `fhevmEnvironment` to it `evm.fhevmEnvironment.interpreter = evm.interpreter` then initialize it `fhevm.InitFhevm(&evm.fhevmEnvironment)`
 
 #### Update RunPrecompiledContract
@@ -143,6 +143,38 @@ to:
 RunPrecompiledContract(p, evm, caller.Address(), addr, input, gas)
 ```
 
+#### Update Create() and Create2() functions
+
+Add code to create ciphertext storage:
+
+```go
+// Create creates a new contract using code as deployment code.
+func (evm *EVM) Create(caller ContractRef, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
+	contractAddr = crypto.CreateAddress(caller.Address(), evm.StateDB.GetNonce(caller.Address()))
+	// Create the ciphertext storage if not already created.
+	if evm.StateDB.GetNonce(fhevm.CiphertextStorageAddress) == 0 {
+		evm.StateDB.CreateAccount(fhevm.CiphertextStorageAddress)
+		evm.StateDB.SetNonce(fhevm.CiphertextStorageAddress, 1)
+	}
+	return evm.create(caller, &codeAndHash{code: code}, gas, value, contractAddr, CREATE)
+}
+
+// Create2 creates a new contract using code as deployment code.
+//
+// The different between Create2 with Create is Create2 uses keccak256(0xff ++ msg.sender ++ salt ++ keccak256(init_code))[12:]
+// instead of the usual sender-and-nonce-hash as the address where the contract is initialized at.
+func (evm *EVM) Create2(caller ContractRef, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
+	codeAndHash := &codeAndHash{code: code}
+	contractAddr = crypto.CreateAddress2(caller.Address(), salt.Bytes32(), codeAndHash.Hash().Bytes())
+	// Create the ciphertext storage if not already created.
+	if evm.StateDB.GetNonce(fhevm.CiphertextStorageAddress) == 0 {
+		evm.StateDB.CreateAccount(fhevm.CiphertextStorageAddress)
+		evm.StateDB.SetNonce(fhevm.CiphertextStorageAddress, 1)
+	}
+	return evm.create(caller, codeAndHash, gas, endowment, contractAddr, CREATE2)
+}
+```
+
 #### Implement EVMEnvironment interface
 
 Now implement the `fhevm.EVMEnvironment` interface for `FhevmImplementation`:
diff --git a/fhevm/evm.go b/fhevm/evm.go
index 5878128..3ddc58e 100644
--- a/fhevm/evm.go
+++ b/fhevm/evm.go
@@ -2,12 +2,10 @@ package fhevm
 
 import (
 	"log/slog"
-	"math/big"
 
 	"github.com/ethereum/go-ethereum/common"
 	"github.com/ethereum/go-ethereum/crypto"
 	"github.com/holiman/uint256"
-	fhevm_crypto "github.com/zama-ai/fhevm-go/fhevm/crypto"
 	"github.com/zama-ai/fhevm-go/fhevm/tfhe"
 )
 
@@ -67,30 +65,3 @@ func insertRandomCiphertext(environment EVMEnvironment, t tfhe.FheUintType) []by
 }
 
 func InitFhevm(accessibleState EVMEnvironment) {}
-
-func Create(evm EVMEnvironment, caller common.Address, code []byte, gas uint64, value *big.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
-	contractAddr = crypto.CreateAddress(caller, evm.GetNonce(caller))
-	protectedStorageAddr := fhevm_crypto.CreateProtectedStorageContractAddress(contractAddr)
-	_, _, leftOverGas, err = evm.CreateContract(protectedStorageAddrCallerAddr, nil, gas, big.NewInt(0), protectedStorageAddr)
-	if err != nil {
-		ret = nil
-		contractAddr = common.Address{}
-		return
-	}
-	// TODO: consider reverting changes to `protectedStorageAddr` if actual contract creation fails.
-	return evm.CreateContract(caller, code, leftOverGas, value, contractAddr)
-}
-
-func Create2(evm EVMEnvironment, caller common.Address, code []byte, gas uint64, endowment *big.Int, salt *uint256.Int) (ret []byte, contractAddr common.Address, leftOverGas uint64, err error) {
-	codeHash := crypto.Keccak256Hash(code)
-	contractAddr = crypto.CreateAddress2(caller, salt.Bytes32(), codeHash.Bytes())
-	protectedStorageAddr := fhevm_crypto.CreateProtectedStorageContractAddress(contractAddr)
-	_, _, leftOverGas, err = evm.CreateContract2(protectedStorageAddrCallerAddr, nil, common.Hash{}, gas, big.NewInt(0), protectedStorageAddr)
-	if err != nil {
-		ret = nil
-		contractAddr = common.Address{}
-		return
-	}
-	// TODO: consider reverting changes to `protectedStorageAddr` if actual contract creation fails.
-	return evm.CreateContract2(caller, code, codeHash, leftOverGas, endowment, contractAddr)
-}