Enc<Owner, T> generic type. Owner specifies who can decrypt the data (Shared or Mxe), and T is the encrypted data type. With Mxe, the nodes can collectively decrypt the data under dishonest-majority assumptions. With Shared, the data is encrypted with a shared secret between the client and the MXE. The wrapper contains the ciphertext, the nonce, and, for Shared ownership, the public key used to encrypt the data.
Encrypted data can be decrypted globally or selectively to a specific user. For global decryption, call the reveal method on any variable with a supported data type. For selective decryption, use sealing, which re-encrypts data for a chosen recipient.
Private inputs are encrypted using the arithmetization-oriented symmetric Rescue cipher. Before the cipher runs, the client and cluster perform an X25519 elliptic curve Diffie-Hellman key exchange to derive a shared secret. The Rescue key is derived by hashing the shared secret with the Rescue-Prime hash function, as described in Section 4, Option 1. This increases the min-entropy of the key.Note:
- Since the X25519 key exchange natively returns shared secrets in the finite field with elements, we implemented Rescue over the field . States in the context of Rescue are elements of the -dimensional vector space , i.e., the Rescue cipher transforms vectors of size to vectors of the same size.
- The security level of the cipher is set to 128 bits.
- We use the Rescue block cipher in Counter (CTR) mode (see Section 6.5), with fixed . The choice is motivated by the fact that it is the smallest value that attains the minimum of recommended rounds (10), given the fixed finite field and security level. The counters have the form
[nonce, i, 0, 0, 0], wherenonceis a 16-byte random value provided by the user. - The hash function used for key derivation is Rescue-Prime over , with
rate = 7andcapacity = 5(i.e., ) and output truncated to 5 field elements. The target security level is set to 256. According to Section 2.2, this offers 256 bits of security against collision, preimage and second-preimage attacks for any field of size at least 102 bits.
input_enc: Enc<Owner, T> can conveniently be obtained by calling input_enc.to_arcis() (the nodes do not learn input; they convert the ciphertext to secret-shares of input by running the Rescue decryption circuit in MPC). If the owner is Shared, the MXE and the client perform a key exchange first. Similarly, owner.from_arcis(output) encrypts the secret-shared output by running the Rescue encryption circuit in MPC.Note:
- After decrypting the user-provided inputs, the MXE increments the
nonceby 1 and uses it for encrypting the outputs. For the forthcoming interaction with the MXE, a newnoncemust be provided. - The performance will benefit from reducing the number of calls to
owner.from_arcis(..)(per owner). Ideally, put all data encrypted toownerin one struct.
EncData<T> contains only ciphertext, omitting pubkey and nonce. Use for multiple outputs to reduce callback payload size.What’s next?
Encrypting inputs
Implement encryption in your TypeScript client.
Sealing
Re-encrypt data between different parties.