Gas Privacy in Secret Contracts

After discussing transactional privacy with @cryptobrypto on Discord, I began to think more about the role of gas in Secret contracts.

I believe the gas fees may reveal a lot about which secret computations occur and may potentially be able to be used as a sidechannel privacy leak of sorts.

For example, take a secret game contract that has a 4 digit pin state internally that we need to guess to win. If a digit was incorrect, contract execution would cease and return a “game over” to the caller. Otherwise execution would continue onto the next digit, until all four were correct and the user won.

By monitoring gas usage, one could deduce each digit of the pin one at a time, by observing when gas spent increased significantly (execution continued to next digit). Is this prevented in any way in Secret?

This is similar to a sidechannel timing attack that is commonly used when one has access to hardware. Even with highly accurate measurements, it usually takes many runs to extract information from such a channel. With contracts, we don’t need to have high accuracy or do many runs - the cycles are reported directly from the gas costs signaled from the enclave (?). Being virtual there’s also no noise or experimental errors to contend with.

Normally, software guards against attacks like these by returning results in a constant (larger) amount of time, so all calls to the sensitive code are identical in length. Generally this may be difficult for Secret to solve in all cases, so may be up to contract developers to prevent, but doing something like having a baseline gas cost, or requiring gas to be spent in 1000 unit increments may go a long way to prevent such disclosures. Alternatively, making something like sSCRT a first-class member so gas expenditure could be secret would solve one side of the cases (the passive case - learning about other’s calls to a contract).

Perhaps I’m missing something, definitely not an expert at Secret yet. If so, I would be interested to learn more about how such attacks are prevented.

4 Likes

You are correct, there are all sorts of side-channel attacks that can be exploited, and some consideration from the contract authors needs to be made per-usecase. For example, we recommend people use the bincode2 package for serializatio of data in storage, rather than json, in order to prevent cyphertext-lengh based sidechannel attacks, you can see a few more examples of possible sidechannels that contract developers may need to protect from here:

(the more interesting attacks imo aren’t side channel attacks, but attacks based on offline techniques that are described there. For example, a consequence of those attacks is that implementing paywalls without an on-chain oracle with a unique code-hash is theoretically exploitable. Not easy, and depends on the exact implementation, but doable)
In the case of your example, the contract should do a constant-time comparison on the pin number. We do this with viewing keys in the SNIP-20 reference, for example.

1 Like

Thanks @uxt! This is a good example to add to this section about data leakage attacks, would you mind sending us a PR? :innocent: