Hashing and Encryption
Hash Functions
MACI uses the Poseidon hash function, which is proven to be very efficient in ZK applications. Poseidon accepts inputs and produces 1 output:
Also, SHA256 is used to compress public inputs to a circuit into a single field element in the finite field mod .
Message Encryption
In order to encrypt messages, MACI uses Poseidon in DuplexSponge mode. This provides an encryption function and a decryption function:
- as
In more details,
- is the shared key, a point on the Baby Jubjub curve
- is the nonce, which we hardcode to 0
- is the length of the plaintext
The implementation can be found here.
Shared Key Generation
The ECDH algorithm is used to generate a shared key, which is then used to encrypt each message. This allows to create messages which are only decryptable by the coordinator and the person sending the message.
In more details:
-
The coordinator's public key is known to all. Their private key is secret.
-
When the user publishes a message (i.e. casts a vote), they generate an ephemeral keypair with private key and public key .
-
The user generates the shared key using the coordinator's public key and the user's ephemeral private key .
-
The user encrypts the command and signature with to form a message.
-
The user sends their ephemeral public key along with the ciphertext. The coordinator can recover the same shared key using their private key and the given ephemeral public key .