The mapping solidity construct uses keccak hash on the key to determine the location (offset) where the corresponding value is stored, and the candidate names (keys) are known. So watching read/writes at the storage interface exposes the number of votes. We could use something like ORAM, but the following is simpler: the number of candidates should be small, so we can just store the counts in a contiguous array, with each 256-bit evm persistent storage location split as a 128-bit nonce-counter and a 128-bit vote count, so that every storage location is rewritten each time a user votes -- we will increment one vote count, but change all nonce/counter values, so that the (encrypted) value written will always change. (This assumes that the storage interface is just the evm storage 256 bit -> 256 bit key-value mapping, which is probably wrong.)
https://github.com/oasislabs/secret-ballot/blob/9294f5a3dc13d129e477c7862476c028acb30aa2/contracts/confidential_SecretBallot.sol#L17
The mapping solidity construct uses keccak hash on the key to determine the location (offset) where the corresponding value is stored, and the candidate names (keys) are known. So watching read/writes at the storage interface exposes the number of votes. We could use something like ORAM, but the following is simpler: the number of candidates should be small, so we can just store the counts in a contiguous array, with each 256-bit evm persistent storage location split as a 128-bit nonce-counter and a 128-bit vote count, so that every storage location is rewritten each time a user votes -- we will increment one vote count, but change all nonce/counter values, so that the (encrypted) value written will always change. (This assumes that the storage interface is just the evm storage 256 bit -> 256 bit key-value mapping, which is probably wrong.)