When a contract is executed on chain the state of the contracts needs to be encrypted so that observers can not see the computation that is initialized. The contract should be able to call certain functions inside the enclave and store the contract state on-chain.
A contract can call 3 different functions: write_db(field_name, value), read_db(field_name), and remove_db(field_name) . It is important that the field_name remains constant between contract calls.
We will go over the different steps associated with the encryption of the contract state.
1. Create contract_key
The contract_key is the encryption key for the contract state and is a combination of two values: signer_id || authenticated_contract_key. Every contract has its own unforgeable encryption key. The concatenation of the values is what makes every unique and this is important for several reasons
Make sure the state of two contracts with the same code is different
Make sure a malicious node runner won't be able to locally encrypt transactions with it's own encryption key, and then decrypt the resulting state with the fake key
so to reiterate, every contract on Secret Network has its own unique and unforgeable encryption key contract_key
This process of creating contract_key is started when the Secret contract is deployed on-chain. First authentication_key is generated using HDKF-SHA256 inside the enclave from the following values:
Lastly concat the signer_id and authenticated_contract_key to create contract_key. This step makes it so the key is unforgeable as the key can only be recreated with the current signer_id
Every time a contract execution is called, contract_key should be sent to the enclave. In the enclave, the following verification needs to happen to proof a genuine contract_key