## Final Report Summary - VON NEUMANN MPC (Secure Multiparty Computation in the von Neumann Architecture)

#### Project context and objectives

One of the breakthrough results of modern cryptography is the existence of *secure multiparty computation*: a way to convert any distributed computation that can be performed securely with the assistance of a trusted third party into a protocol that does not require any third parties, yet gives the same output and remains just as secure. These results appear to be extremely relevant for problems in many areas—wherever there is tension between privacy, trust and functionality. Examples included running sealed-bid auctions without a trusted auctioneer, privately performing computations “in the cloud” and verifiable voting with secret ballots.

Existing generic secure computation techniques involve translating a function to be computed into a logical circuit. Like a digital electrical circuit, the logical circuit is composed of gates connected by logical wires. Each gate computes a very simple function of its input wires (e.g. logical *or*, *and* or *not*).

In this project we took a different avenue towards practical secure computation: changing it from a “hardware engineering” problem (designing circuits) to one of “software engineering” (writing programs). By relaxing the security definition a little (to allow the secure computation to reveal its total running time), this model could make it feasible to compute functions whose circuit representation is too large for existing techniques to handle. Moreover, in this architecture it is possible to compile secure programs directly from standard programming languages (such as C or Java). We hope this will make secure computation accessible to the many software engineers who already know how to program but do not have time to learn new, domain-specific languages or circuit design.

#### Main results

The project consists of both theoretical and implementation components.

On the practical front, we have developed a software library for running a secure computation “virtual machine” (we call this the Inchworm Virtual Machine). By constructing a toolkit aimed at the “average programmer”, together with sample applications that demonstrate its usefulness, we hope to repeat the success of now standard cryptographic tools, such as public-key encryption and digital signatures.

We now have a working virtual machine for secure computation, written in Java. The implementation contains a built-in assembler/disassembler, supporting symbolic addresses and inline evaluation of (constant) arithmetic expressions. In addition, we have written an LLVM backend that targets the Inchworm virtual machine, allowing C programs to be compiled to Inchworm assembly.

We have also written several benchmark “applications” in both C and the Inchworm assembly language, including an implementation of the SHA-1 and SHA-256 hash functions, the AES block cipher, secure computation of the GCD of two integers and multiplication of big integers. These assembly programs are already useful as test cases for the virtual machine implementation and for evaluating the “programmer experience” when working with the Inchworm platform. They are also stepping stones towards applications that may have practical use, such as secure computation of an RSA public key.

The planning for initial implementation originally called for a circuit-based CPU, implemented using standard secure-computation techniques. However, during our preliminary research and design phase, we observed that such a monolithic design is not necessary. Instead, our virtual CPU design relies on a new idea: each “instruction” of the virtual CPU is composed of several operations (ops), and each op is a separate secure computation. For example, an instruction might be composed of a LOADREG (an indirect read from a register), several arithmetic ops (e.g. ADD, XOR, etc.) and a STOREREG (and indirect write to a register). Since each op is a separate secure computation, its implementation can be tailored for that particular operation. In particular, we can “mix and match” between secure computation protocols and choose the best one for each op.

In our implementation, we make use of this property extensively. For example, we implement the LOAD and STORE operations using a new dedicated protocol we call FastMUX, based only on (black-box) oblivious transfer (which itself is implemented using OT extension protocols, and thus requires almost no computation overhead). In comparison testing, our FastMUX protocol beats both the naïve circuit-based MUX and ORAM implementations for memory sizes of up to several gigabytes. The arithmetic operations are currently implemented using circuit-based secure computation (for this purpose we are currently using code based on the FastGC secure computation library from the University of Virginia).

An additional advantage of our design choice is extreme modularity. It is easy to test and compare different implementations of a single op, without changing the rest of the code. This design also lends itself to easier debugging of both the infrastructure and application (Inchworm assembly) code—this is something that secure computation can make much harder to do, since the application (by design) runs in a completely “opaque” manner. Using the modular design, we can swap out the secure op implementation with “dummy” implementations that have the same functionality but do not use secure computation; these can be easily inspected during runtime (using a standard Java debugger, or via logging infrastructure).

A second innovation in the current design stems from the observation that, while the number of ops in an instruction and their order must be known to all the computing parties (and thus cannot depend on the secret state of the CPU), we do not have to use the same ops in each instruction. For example, a DIV op (secure computation of a division operation) is extremely expensive compared to an ADD; if we required every instruction to contain a DIV, efficiency would be significantly impacted. To solve this problem, we allow each op to have a different frequency: for example, we can specify that an ADD op is included in every instruction, while a DIV op is only executed once every hundred instructions. This allows an Inchworm assembly program to benefit from a DIV instruction (executed rarely), without paying the price in each instruction.

On the theoretical side, we have several new results in related areas:

- *One-Way Functions and (Im)perfect Obfuscation*: We considered a basic question about the relation between indistinguishability Obfuscation (iO) and one-way functions, taking a step towards proving that if $\textrm{P}\ne\textrm{NP}$ then efficient iO implies one-way functions (we showed the implication when $\textrm{NP}\nsubseteq\textrm{io-BPP}$).

- *Topology-Hiding Computation*: We studied multiparty computation in a setting where parties are connected by a *partial* communication graph (as opposed to a broadcast channel or a full point-to-point network), where one of the security objectives is hiding information about the communication graph itself. Our research was one of the first to consider this question, and we provided both negative and positive results (on the positive side, we constructed a protocol for topology-hiding computation in the semi-honest model, on graphs with logarithmic diameter, while on the negative we showed impossibility results in the fail-stop model).

- *Public Verification of Private Effort*: We studied the problem of converting privately-verifiable proofs into a publicly-verifiable protocol. In this context, we proposed a new “effort” based polling protocol whose results can be publicly verified, without having to trust the pollster for faithfully announcing the poll’s results or relying on strong identity verification (which is very hard to achieve in an Internet setting).

- *How to Use Bitcoin to Play Decentralized Poker*: We generalized “traditional” secure multiparty computation to a setting with money—where in addition to the standard (informational) inputs and outputs, parties can also submit money as input to the computation, and the resulting computation can distribute the money to the parties. We show how to construct a protocol for general “secure cash distribution”, relying on an ideal primitive that can be implemented by existing crypto-currencies, as well as a more efficient protocol specifically for card games (such as Poker).

- *Proofs of Space-Time and Rational Proofs of Storage*: In the context of crypto-currencies, we propose a replacement to the using “proofs-of-work” (PoWs) as the underlying proof of resource consumption. Our protocol can be used instead to prove that a user “wasted” storage space for a given amount of time. This has the advantage of being far more energy efficient, which is both more environmentally friendly and allows lower transaction fees. Our definitions are in the same spirit as previous work on “Proofs of Space” (patching some holes in the original definitions), but our construction is completely different (and can be thought of as complementary).[^1]

#### Public web-site

The software library source and documentation have been published under an open-source license on GitHub (http://github.com/factcenter/inchworm ), and linked from the project website at