Algorithms

Our JavaScript SDK allows you to use either secure multi-party computation (SMC) or fully homomorphic encryption (FHE) to privately compute on sensitive data. For example, using SMC, a patient can learn about their disease risks without ever needing to send unprotected sensitive data to a doctor. Similarly, using FHE a consumer can learn about financial products relevant to them without needing to share unencrypted financial data with a lender.


1. SMC or FHE?

The table below covers some of the major differences between the two methods and helps you to pick the right one for you. High level - if your application is very sensitive to running time or you would like to provide a good user experience even on older phones, consider SMC. Otherwise, we recommend FHE.

# FHE SMC
Key generation 4 keys No keys
Coefficients Integer Float
Number of API requests 3 7
Speed 50 seconds 5 seconds
Security FHE is more secure than SMC

2. Secure Multiparty Computation (SMC)

In SMC, there are generally three or more parties, all with distinct roles.

Party 1 - The User enters (or otherwise provides) data and clicks 'compute'. After some delay - a few seconds - the result of the computation is displayed to them.
Party 2 - The Algorithm Provider provides an algorithm, such as a linear function with N terms (and therefore N coefficients). From a developer perspective, you need to name your algorithm and specify its coefficients (on the API side) and configure and call our API (on the client side).
Party 3 - The Random Number Provider provides special pairs of random numbers to the other parties. Using these random numbers and by sharing computation intermediates, the edge client (and/or the algorithm provider) can ultimately see the final result. In this type of computation, no party shares unprotected information with the other parties. For more details, see our technology page.

Here is what happens under the hood. After receiving inputs from the App user, EnyaSMC.Linear() requests random numbers, splits inputs, mixes the random numbers with the inputs, and shares some of the resulting values with the algorithm provider. That party also obtains random numbers and uses them to protect their secrets, in this case, their algorithm coefficients. To learn more, here is the 1991 publication on Beaver Triples (Efficient Multiparty Protocols Using Circuit Randomization).

Notes: SMC requires far less computation client-side since it does not involve traditional key generation, except for needing Beaver Triples (which can be precomputed). However, compared to FHE, SMC involves multiple cycles of secret sharing with multiple servers and is therefore more dependent on reliable networking.


3. SMC - Algorithms/Notes

We currently support simple linear functions on input data vectors. For example, a suitable linear function could be obtained through a linear regression on training data. Assuming your algorithm is $$f(y) = \beta_1\times x_1 + \beta_2\times x_2 + \beta_3\times x_3 + \beta_4\times x_4,$$ then your algorithm coefficients and user inputs would be \([\beta_1, \beta_2, \beta_3, \beta_4]\) and \([x_1, x_2, x_3, x_4]\), respectively. To give a specific example, imagine your algorithm is $$f(y) = 0.3\times x_1 + 6\times x_2 + 0.34\times x_3 + 9\times x_4,$$ then your algorithm coefficients would be \([0.3, 6, 0.34, 9]\). As explained in the Quick Start, you can use algo_add.py to give your linear algorithm a convenient name (e.g. "CreditScore", "DiseaseRisk", or "LifeExpectancy") and specify the number of terms and its coefficients. In this example, when running algo_add.py you would set the model coefficients to '[0.3, 6, 0.34, 9]'. See Quick Start to learn more.

These are several other considerations:

  1. There is no limitation on the number of algorithm coefficients.

  2. There is a limitation on the absolute magnitude of inputs, coefficients, and the results. If you have a coefficient such as \(\beta \times 10^{15}\)​ and an inputs such as \(x \times 10^{-5}\), consider balancing them (i.e. \(\beta \times 10^5\) and \(x \times 10^5\)) to facilitate calculations. Likewise, when your calculations might return values greater than \(10^{15}\), consider reformulating the inputs and the algorithm coefficients - you can always multiply the computation results on the App side by a suitable factor before using the returned values.

  3. The value of the optimal bitlength scales with the values of the input coefficients and the largest value of it is 10. Any positive integer can be used, but excessive bitlengths might cause errors by exceeding make numbers larger than the safe integers in JavaScript and cause errors. The default value should handle most calculations.


4. Fully Homomorphic Encryption (FHE)

We use the BFVrns FHE scheme, which can can encrypt and decrypt all-integer vectors. FHE requires at least four keys (which must first be generated) and uses one of those keys (the public key) to encrypt the data. Once encrypted, FHE sends the ciphertext and compute authorization keys to the server and then checks for completion of the computation. Upon completion of the calculation, the SDK retrieves the result and decrypts it. FHE is generally more secure than SMC, since fewer parties are involved (typically only two) and all security relevant operations are executed client side. SMC involves at least three parties and the entire system can be jeopardized by a dishonest Beaver Triple provider. By contrast, in FHE, only lattice-crypto secured data leave the phone and therefore, even a malicious data recipient cannot see the sensitive data.


5. FHE - Algorithms/Notes

Our test environment is React Native running on current phone hardware, such as an iPhone X, iPhone 11, or Samsung Galaxy Note 10. The actual FHE execution time will vary across devices and test environments. On an iPhone 11, FHE needs about 40 seconds to generate the four required keys (private key, public key, multiplication key, rotation key) - this process involves generating a large number of random integers. Since the heavy computation would otherwise block the UI, we use the next-frame package to maintain UI responsiveness during key generation.