Wys

. Secure multi-party computation (MPC) enables a set of mutually distrusting parties to cooperatively compute, using a cryptographic protocol, a function over their private data. This paper presents Wys (cid:63) , a new domain-speciﬁc language (DSL) for writing mixed-mode MPCs. Wys (cid:63) is an embedded DSL hosted in F (cid:63) , a veriﬁcation-oriented, eﬀect-ful programming language. Wys (cid:63) source programs are essentially F (cid:63) programs written in a custom MPC eﬀect, meaning that the programmers can use F (cid:63) ’s logic to verify the correctness and security properties of their programs. To reason about the distributed runtime semantics of these programs, we formalize a deep embedding of Wys (cid:63) , also in F (cid:63) . We mechanize the necessary metatheory to prove that the properties veriﬁed for the Wys (cid:63) source programs carry over to the distributed, multi-party semantics. Finally, we use F (cid:63) ’s extraction to extract an interpreter that we have proved matches this semantics, yielding a partially veriﬁed implementation. Wys (cid:63) is the ﬁrst DSL to enable formal veriﬁcation of MPC programs. We have implemented several MPC protocols in Wys (cid:63) , including private set intersection, joint median, and an MPC-based card dealing application, and have veriﬁed their correctness and security.


Introduction
Secure multi-party computation (MPC) enables two or more parties to compute a function f over their private inputs x i so that parties don't see each others' inputs, but rather only see the output f (x 1 , ..., x n ).Using a trusted third party to compute f would achieve this goal, but in fact we can achieve it using one of a variety of cryptographic protocols carried out only among the participants [12,26,57,64].One example use of MPC is private set intersection (PSI): the x i could be individuals' personal interests, and the function f computes their intersection, revealing which interests the group has in common, but not any interests that they don't.MPC has also been used for auctions [18], detecting tax fraud [16], managing supply chains [33], privacy preserving statistical analysis [31], and more recently for machine learning tasks [19,21,30,38,44].
Typically, cryptographic protocols expect f to be specified as a boolean or arithmetic circuit.Programming directly with circuits and cryptography is painful, so starting with the Fairplay project [40] many researchers have designed higher-level domain-specific languages (DSLs) in which to program MPCs [6,14,17,19,23,27,29,34,37,39,45,48,49,52,55,60].These DSLs compile source code to circuits which are then given to the underlying protocol.While doing this undoubtedly makes it easier to program MPCs, these languages still have several drawbacks regarding both security and usability.
This paper presents Wys , a new MPC DSL that addresses several problems in prior DSLs.Unlike most previous MPC DSLs, Wys is not a standalone language, but is rather an embedded DSL hosted in F [58], a full-featured, verification-oriented, effectful programming language.Wys has the following two distinguishing elements: 1.A program logic for MPC. ( §2 and §3.)In their most general form, MPC applications are mixed-mode: they consist of parties performing (potentially different) local, in-clear computations (e.g.I/O, preprocessing inputs) interleaved with joint, secure computations.Wys is the first MPC DSL to provide a program logic to formally reason about the correctness and security of such applications, e.g., to prove that the outputs will not reveal too much information about a party's inputs [41]. 3o avoid reasoning about separate programs for each party, Wys builds on the basic programming model of the Wysteria MPC DSL [52] that allows applications to be written as a single specification.Wys presents a shallow embedding of the Wysteria programming model in F .When writing Wys source programs, programmers essentially write F programs in a new Wys effect, against a library of MPC combinators.The pre-and postcondition specifications on the combinators encode a program logic for MPC.The logic provides observable traces-a novel addition to the Wysteria semantics-which programmers can use to specify security properties such as delimited release [54].Since Wys programs are F programs, F computes verification conditions (VCs) for them which are discharged using Z3 [2] as usual.
We prove the soundness of the program logic-that the properties proven about the Wys source programs carry over when these programs are run by multiple parties in a distributed manner-also in F .The proof connects the pre-and postconditions of the Wys combinators to their distributed semantics in two steps.First, we implement the combinators in F , proving the validity of their pre-and postconditions of against their implementation.Next, we reason about this implementation and the distributed runtime semantics through a deepembedding of Wys in F .Essentially, we deep-embed the Wys combinator abstract syntax trees (ASTs) as an F datatype and formalize two operational semantics for them: a conceptual single-threaded semantics that models their F implementation, and the actual distributed semantics that models the multi-party runs of the programs.We prove, in F , that the single-threaded semantics is sound with respect to the distributed semantics ( §3).While we use F , the program logic is general and it should be possible to embed it in other verification frameworks (e.g., in Coq, in the style of Hoare Type Theory [46]).
2. A full-featured, partially verified implementation ( §3.) Wys 's implementation is, in part, formally verified.The hope is that formal verification will reduce the occurrence of security threatening bugs, as it has in prior work [15,36,50,62,63].
We define an interpreter in F that operates over the Wys ASTs produced by a custom F extraction for the Wys effect.While the local computations are executed locally by the interpreter, the interpreter compiles secure-computation ASTs to circuits, on the fly, and executes them using the Goldreich, Micali and Wigderson (GMW) multi-party computation protocol [26].The Wys AST (and hence the interpreter) does not "bake in" standard F constructs like numbers and lists.Rather, inherited language features appear abstractly in the AST, and their semantics is handled by a foreign function interface (FFI).This permits Wys programs to take advantage of existing code and libraries available in F .
To prove the interpreter behaves correctly, we prove, in F , that it correctly implements the formalized distributed semantics.The circuit library and the GMW implementation are not verified-while it is possible to verify the circuit library [4], verifying a GMW implementation is an open research question.But the stage is set for verified versions to be plugged into the Wys codebase.We characterize the Trusted Computing Base (TCB) of the Wys toolchain in §3. 5.
Using Wys we have implemented several programs, including PSI, joint median, and a card dealing application ( §4).For PSI and joint median we implement two versions: a straightforward one and an optimized one that improves performance but increases the number of adversary-observable events.We formally prove that the optimized and unoptimized versions are equivalent, both functionally and w.r.t.privacy of parties' inputs.Our card dealing application relies on Wys 's support for secret shares [56].We formally prove that the card dealing algorithm always deals a fresh card.
In sum, Wys constitutes the first DSL that supports proving security and correctness properties about MPC programs, which are executed by a partially verified implementation of a full-featured language.No prior DSL provides these benefits ( §5).The Wys implementation, example programs, and proofs are publicly available on Github at https://github.com/FStarLang/FStar/tree/stratified_last/examples/wysteria. 4

Verifying and deploying Wys programs
We illustrate the main concepts of Wys by showing, in several stages, how to program, optimize, and verify the two-party joint median example [32,53].In this example, two parties, Alice and Bob, each have a set of n distinct, locally sorted integers, and they want to compute the median of the union of their sets without revealing anything else; our running example fixes n = 2, for simplicity.

Secure computations with as sec
In Wys , as in its predecessor Wysteria [52], an MPC is written as a single specification that executes in one of two computation modes.The primary mode is called sec mode.In it, a computation is carried out using a MPC protocol among multiple principals on separate hosts.Here is joint median in Wys : The four arguments to median are, respectively, principal identifiers for Alice and Bob, and Alice and Bob's secret inputs expressed as tuples.In Wys , values specific to each principal are sealed with the principal's name (which appears in the sealed container's type).As such, the types of in a and in b are, respectively, sealed {a} (int * int) and sealed {b} (int * int).The as sec ps f construct indicates that thunk f should be run in sec mode among principals in the set ps.In this mode, the code has access to the secrets of the principals ps, which it can reveal using the reveal coercion.As we will see later, the type of reveal ensures that parties cannot reveal each others' inputs outside sec mode. 5Also note that the code freely uses standard F library functions like fst and snd.The example extends naturally to n > 2 [3].
To run this program, both Alice and Bob would start a Wys interpreter at their host and direct it to run the median function Upon reaching the as sec thunk, the interpreters coordinate with each other to compute the result using the underlying MPC protocol.§2.5 provides more details.

Optimizing median with as par
Although median gets the job done, it can be inefficient for large n.However, it turns out if we reveal the result of comparison on line 2 to both the parties, then the computation on line 3 (resp.line 4) can be performed locally by Alice (resp.Bob) without need of cryptography.Doing so can massively improve performance: previous work [32] has observed a 30× speedup for n = 64.
This optimized variant is a mixed-mode computation, where participants perform some local computations interleaved with small, jointly evaluated secure computations.Wys 's second computation mode, par mode, supports such mixed-mode computations.The construct as par ps f states that each principal in ps should locally execute the thunk f, simultaneously; any principal not in the set ps simply skips the computation.Within f, while running in par mode, principals may engage in secure computations via as sec.
Here is an optimized version of median using as par: The secure computation on (line 2) only computes cmp and returns the result to both the parties.Line 3 is then a par mode computation involving only Alice in which she discards one of her inputs based on cmp.Similarly, on line 4, Bob discards one of his inputs.Finally, line 5 compares the remaining inputs using as sec and returns the result as the final median.
One might wonder whether par mode is necessary.Could we program the local parts of a mixed-mode program in normal F , and use a special compiler to convert the sec mode parts to circuits and pass them to a GMW MPC service?We could, but it would complicate both writing MPCs and formally reasoning that the whole computation is correct and secure.In particular, programmers would need to write one program for each party that performs a different local computation (as in median opt).The potential interleaving among local computations and their synchronization behavior when securely computing together would be a source of possible error and thus must be considered in any proof.For example, Alice's code might have a bug in it that prevents it from reaching a synchronization point with Bob, to do a GMW-based MPC.For Wys , the situation is much simpler.Programmers may write and maintain a single program.This program can be formally reasoned about directly using a SIMD-style, "single-threaded" semantics, per the soundness result from §3.4.This semantics permits reasoning about the coordinated behavior of multiple principals, without worry about the effects of interleavings or wrong synchronizations.Thanks to par mode, invariants about coordinated local computations are directly evident since we can soundly assume about lockstep behavior (e.g., loop iterations in the PSI example in §4).

Embedding a type system for Wys in F
Designing high-level, multi-party computations is relatively easy using Wysteria's abstractions.Before trying to run such a computation, we might wonder: 1. Is it realizable?For example, does a computation that is claimed to be executed only by some principals ps (e.g., using an as par ps or an as sec ps) only ever access data belonging to ps? 2. Is it correct?For example, does median opt correctly compute the median of Alice and Bob's inputs? 3. Is it secure?For example, do the optimizations in median opt, which produce more visible outputs, potentially leak more about the inputs?
By embedding Wys in F and leveraging its extensible, monadic, dependent type-and-effect system, we address each of these three questions.We define a new indexed monad called Wys for computations that use MPC combinators as sec and as par.Using Wys along with the sealed type, we can ensure that protocols are realizable.Using F 's capabilities for formal verification, we can reason about a computation's correctness.By characterizing observable events as part of Wys, we can define trace properties of MPC programs, to reason about security.
To elaborate on the last: we are interested in application-level security properties, assuming that the underlying cryptographic MPC protocol (GMW [26] in our implementation) is secure.In particular, the Wys monad models the ideal behavior of sec mode-a secure computation reveals only the final output and nothing else.Thus the programmer could reason, for example, that optimized MPC programs reveal no more than their unoptimized versions.To relate the proofs over ideal functionality to the actual implementation, as is standard, we rely on the security of the cryptographic protocol and the composition theorem [20] to postulate that the implementation securely realizes the ideal specification.
The Wys monad.The Wys monad provides several features.First, all DSL code is typed in this monad, encapsulating it from the rest of F .Within the monad, computations and their specifications can make use of two kinds of ghost state: modes and traces.The mode of a computation indicates whether the computation is running in an as par or in an as sec context.The trace of a computation records the sequence and nesting structure of outputs of the jointly executed as sec expressions-the result of a computation and its trace constitute its observable behavior.The Wys monad is, in essence, the product of a reader monad on modes and a writer monad on traces [43,61].
Formally, we define the following F types for modes and traces.A mode Mode m ps is a pair of a mode tag (either Par or Sec) and a set of principals ps.A trace is a forest of trace element (telt) trees.The leaves of the trees record messages TMsg x that are received as the result of executing an as sec thunk.The tree structure represented by the TScope ps t nodes record the set of principals that are able to observe the messages in the trace t.The type indicates that e is in the Wys monad (so it may perform multi-party computations); t is its result type; pre is a pre-condition on the mode in which e may be executed; and post is a post-condition relating the computation's mode, its result value, and its trace of observable events.When run in a context with mode m satisfying the pre-condition predicate pre m, e may produce the trace tr, and if and when it returns, the result is a t-typed value v validating post m v tr.The style of indexing a monad with a computation's pre-and post-condition is a standard technique [7,47,58]-we defer the definition of the monad's bind and return to the actual implementation and focus instead on specifications of Wys specific combinators.We describe as sec, reveal, and as par, and how we give them types in F , leaving the rest to Figure 10  The type of as sec is dependent on the first parameter, ps.Its second argument f is the thunk to be evaluated in sec mode.The result's computation type has the form Wys a (requires φ) (ensures ψ), for some pre-condition and post-condition predicates φ and ψ, respectively.We use the requires and ensures keywords for readability-they are not semantically significant.
The pre-condition of as sec is a predicate on the mode m of the computation in whose context as sec ps f is called.For all the ps to jointly execute f, we require all of them to transition to perform the as sec ps f call simultaneously, i.e., the current mode must be Mode Par ps.We also require the pre-condition pre of f to be valid once the mode has transitioned to Mode Sec ps-line 2 says just this.
The post-condition of as sec is a predicate relating the initial mode m, the result r:a, and the trace tr of the computation.Line 3 states that the trace of a secure computation as sec ps f is just a singleton [TMsg r], reflecting that its execution reveals only result r.Additionally, it ensures that the result r is related to the mode in which f is run (Mode Sec ps) and some trace t according to post, the post-condition of f.The API models the "ideal functionality" of secure computation protocols (such as GMW) where the participants only observe the final result.
Defining reveal in Wys .As discussed earlier, a value v of type sealed ps t encapsulates a t value that can be accessed by calling reveal v.This call should only succeed under certain circumstances.For example, in par mode, Bob should not be able to reveal a value of type sealed {Alice} int.The type of reveal makes the access control rules clear: The unseal function is a Ghost function, meaning that it can only be used in specifications for reasoning purposes.On the other hand, reveal can be called in the concrete Wys programs.Its precondition says that when executing in Mode Par ps', all current participants must be listed in the seal, i.e., ps' ⊆ ps.However, when executing in Mode Sec ps', only a subset of current participants is required: ps' ∩ ps = ∅.This is because the secure computation is executed jointly by all of ps', so it can access any of their individual data.The postcondition of reveal relates the result r to the argument x using the unseal function.
Defining as par in Wys .The type of as par enforces the current mode to be Par, and ps to be a subset of current principals.Importantly, the API scopes the trace t of f to model the fact that any observables of f are only visible to the principals in ps.Note that as sec did not require such scoping, as there ps and the set of current principals in m are the same.

Correctness and security verification
Using the Wys monad and the sealed type, we can write down precise types for our median and median opt programs, proving various useful properties.We discuss the statements of the main lemmas and the overall proof structure.By programming the protocols as a single specification using the high-level abstractions provided by Wys , our proofs are relatively straightforward-in all the proofs of this section, F required no additional hints.In particular, we rely heavily on the view that both parties execute (different fragments of) the same code, thus avoiding the unwieldy task of reasoning about low-level message passing.
Correctness and security of median.We first define a pure specification of median of two int tuples: Further, we capture the preconditions using the following predicate: Using these, we prove the following top-level specification for median: This signature establishes that when Alice and Bob simultaneously execute median (in Par mode), with secrets in a and in b, then if and when the protocol terminates, (a) if their inputs satisfy the precondition median pre, then the result is the joint median of their inputs and (b) the observable trace consists only of the final result, as there is but a single as sec thunk in median, i.e., it is secure.
Correctness and security of median opt.The security proof of median opt is particularly interesting, because the program intentionally reveals more than just the final result, i.e., the output of the first comparison.We would like to verify that this additional information does not compromise the privacy of the parties' inputs.To do this, we take the following approach.
First, we characterize the observable trace of median opt as a pure, specificationonly function.Then, using relational reasoning, we prove a noninteference with delimited release property [54] on these traces.Essentially we prove that, for two runs of median opt where Bob's inputs and the output median are the same, the observable traces are also same irrespective of Alice's inputs.Thus, from Alice's perspective, the observable trace does not reveal more to Bob than what the output already does.We prove this property symmetrically for Bob.
We start by defining a trace function for median opt: The delimited release property is then captured by the following lemma: The lemma proves that for two runs of median opt where Bob's input and the final output remain same, but Alice's inputs vary arbitrarily, the observable traces are the same.As such, no more information about information leaks about Alice's inputs via the traces than what is already revealed by the output.We also prove a symmetrical lemma median opt is secure for bob.
In short, because the Wys monad provides programmers with the observable traces in the logic, they can then be used to prove properties, relational or otherwise, in the pure fragment of F outside the Wys monad.We present more examples and their verification details in §4.

Deploying Wys programs
Having defined a proved-secure MPC program in Wys , how do we run it?Doing so requires the following steps (Figure 1).First, we run the F compiler in a special mode that extracts the Wys code (say psi.fst), into the Wys AST as a data structure (in psi.ml).Except for the Wys specific nodes (as sec, as par, etc.), the rest of the program is extracted into FFI nodes that indicate the use of, or calls into, functionality provided by F itself.
The next step is for each party to run the extracted AST using the Wys interpreter.This interpreter is written in F and we have proved (see §3.5) it implements a deep embedding of the Wys semantics, also specified in F (Figures 5 and 6,  §3).The interpreter is extracted to OCaml by the usual F extraction.Each party's interpreter executes the AST locally until it reaches an as sec ps f node, where the interpreter's back-end compiles f, on-the-fly, for particular values of the secrets in f's environment, to a boolean circuit.Firstorder, loop-free code can be compiled to a circuit; Wys provides specialized support for several common combinators (e.g., fst, snd, list combinators such as List.intersect,List.mem,List.nth etc.).
The circuit is handed to a library by Choi et al. [22] that implements the GMW [26] MPC protocol.Running the GMW protocol involves the parties in ps generating and communicating (XOR-based) secret shares [56] for their secret inputs, and then cooperatively evaluating the boolean circuit for f over them.
One obvious question is how both parties are able to get this process off the ground, given that they don't know some of the inputs (e.g., other parties' secrets).The sealed abstraction helps here.Recall that for median, the types of the inputs are of the form sealed {a} (int * int) and sealed {b} (int * int).When the program is run on Alice's host, the former will be a pair of Alice's values, whereas the latter will be an opaque constant (which we denote as •).The reverse will be true on Bob's host.When the circuit is constructed, each principal links their non-opaque inputs to the relevant input wires of the circuit.Similarly, the output map component of each party is derived from their output wires in the circuit, and thus, each party only gets to see their own output.

Formalizing and implementing Wys
In the previous section, we presented examples of verifying properties about Wys programs using F 's logic.However, these programs are not executed using the F (single-threaded) semantics; they have a distributed semantics involving multiple parties.So, how do the properties that we verify using F carry over?
In this section, we present the metatheory that answers this question.First, we formalize the Wys single-threaded (ST) semantics, that faithfully models the F semantics of the Wys API presented in §2.Next, we formalize the distributed (DS) semantics that multiple parties use to run Wys programs.Then we prove the former is sound with respect to the latter, so that properties proved of programs under ST apply when run under DS.We have mechanized the proof of this theorem in F .

Syntax
Figure 2 shows the complete syntax of Wys .Principals and principal sets are first-class values, and are denoted by p and s respectively.Constants in the language also include () (unit), booleans, and FFI constants c.Expressions e include the regular forms for functions, applications, let bindings, etc. and the Wys -specific constructs.Among the ones that we have not seen in §2, expression mkmap e 1 e 2 creates a map from principals in e 1 (which is a principal set) to the value computed by e 2 .project e 1 e 2 projects the value of principal e 1 from the map e 2 , and concat e 1 e 2 concatenates the two maps.The maps are used if an as sec computation returns different outputs to the parties.
Host language (i.e., F ) constructs are also part of the syntax of Wys , including constants c include strings, integers, lists, tuples, etc.Likewise, host language functions/primitives can be called from Wys -ffi f ē is the invocation of a host-language function f with arguments ē.The FFI confers two benefits.First, it simplifies the core language while still allowing full consideration of security relevant properties.Second, it helps the language scale by incorporating many of the standard features, libraries, etc. from the host language.

Single-threaded semantics
We formalize the semantics in the style of Hieb and Felleisen [24], where the redex is chosen by (standard, not shown) evaluation contexts E, which prescribe left-to-right, call-by-value evaluation order.The ST semantics, a model of the F semantics and the Wys API, defines a judgment C → C that represents a single step of an abstract machine (Figure 4).Here, C is a configuration M ; X; L; T ; e.This five-tuple consists of a mode M , a stack X, a local environment L, a trace T , and an expression e.The syntax for these elements is given in Figure 3.The value form v represents the host language (FFI) values.The stack and environment are standard; trace T and mode M were discussed in the previous section.
For space reasons, we focus on the two main Wys constructs as par and as sec.Appendix B shows rules for other Wys specific constructs.Rules S-aspar and S-parret (Figure 4) reduce an as par expression once its arguments are fully evaluated-its first argument s is a principal set, while the second argument (L 1 , λx.e) is a closure where L 1 captures the free variables of thunk λx.e.S-aspar first checks that the current mode M is Par and contains all the principals from the set s.It then pushes a seal s frame on the stack, and starts evaluating e under the environment L 1 [x → ()].The rule S-asparret pops the frame and seals the result, so that it is accessible only to the principals in s.The rule also creates a trace element TScope s T , essentially making observations during the reduction of e (i.e., T ) visible only to principals in s.
Turning to as sec, the rule S-assec checks the precondition of the API, and the rule S-assecret generates a trace observation TMsg v, as per the postcondition of the API.As mentioned before, as sec semantics models the ideal, trusted third-party semantics of secure computations where the participants only observe the final output.We can confirm that the rules implement the types of as par and as sec shown in §2.

Distributed semantics
In the DS semantics, principals evaluate the same program locally and asynchronously until they reach a secure computation, at which point they synchronize to jointly perform the computation.The semantics consists of two parts: (a) a judgment of the form π −→ π (Figure 5), where a protocol π is a tuple (P ; S) such that P maps each principal to its local configuration and S maps a set of principals to the configuration of an ongoing, secure computation; and (b) a local evaluation judgment C C (Figure 6) to model how a single principal behaves while in par mode.
Rule P-Par in Figure 5 models a single party taking a step, per the local evaluation rules.Figure 6 shows these rules for as par.(See Appendix B for more local evaluation rules.)A principal either participates in the as par computation, or skips it.Rules L-aspar1 and L-parret handle the case when p ∈ s, and so, the principal p participates in the computation.The rules closely mirror the corresponding ST semantics rules in Figure 4.One difference in the rule L-asparret is that the trace T is not scoped.In the DS semantics, traces only contain TMsg elements; i.e., a trace is the (flat) list of secure computation outputs observed by that active principal.If p ∈ s, then the principal skips the computation with the result being a sealed value containing the opaque constant • (rule L-aspar2).The contents of the sealed value do not matter, since the principal will not be allowed to unseal the value anyway.
As should be the case, there are no local rules for as sec-to perform a secure computation parties need to combine their data and jointly do the computation.Rule P-enter in Figure 5 handles the case when principals enter a secure computation.It requires that all the principals p ∈ s must have the expression form as sec s (L p , λx.e), where L p is their local environment associated with the closure.Each party's local environment contains its secret values (in addition to some public values).Conceptually, a secure computation combines these environments, thereby producing a joint view, and evaluates e under the combination.We define an auxiliary combine function for this purpose: The rule P-enter combines the principals' environments, and creates a new entry in the S map.The principals are now waiting for the secure computation to finish.Rule P-sec models a stepping rule inside the sec mode.
The rule P-exit applies when a secure computation has completed and returns results to the waiting principals.If the secure computation terminates with value v, each principal p gets the value slice v p v. The slice v function is analogous to combine, but in the opposite direction-it strips off the parts of v that are not accessible to p: In the rule P-exit, the notation is defined as: M ; X; L; T ; v = M ; X; L; append T [TMsg v]; v That is, the returned value is also added to the principal's trace to note their observation of the value.

Metatheory
Our goal is to show that the ST semantics faithfully represents the semantics of Wys programs as they are executed by multiple parties, i.e., according to the DS semantics.We do this by proving simulation of the ST semantics by the DS semantics, and by proving confluence of the DS semantics.Our F development mechanizes all the metatheory presented in this section.
Simulation.We define a slice s C function that returns the corresponding protocol π C for an ST configuration C. In the P component of π C , each principal p ∈ s is mapped to their slice of the protocol.For slicing values, we use the same slice v function as before.Traces are sliced as follows: The slice of an expression (e.g., the source program) is itself.For all other components of C, slice functions are defined analogously.
We say that C is terminal if it is in Par mode and is fully reduced to a value (i.e. when C = ; X; ; ; e, e is a value and X is empty).Similarly, a protocol π = (P, S) is terminal if S is empty and all the local configurations in P are terminal.The simulation theorem is then the following: Theorem 1 (Simulation of ST by DS).Let s be the set of all principals.If C 1 → * C 2 , and C 2 is terminal, then there exists some derivation (slice s C 1 ) −→ * (slice s C 2 ) such that (slice s C 2 ) is terminal.
To state confluence, we first define the notion of strong termination.
Definition 1 (Strong termination).If all possible runs of protocol π terminate at π t , we say π strongly terminates in π t , written π ⇓ π t .
Combining the two theorems, we get a corollary that establishes the soundness of the ST semantics w.r.t. the DS semantics: Corollary 1 (Soundness of ST semantics).Let s be the set of all principals.If C 1 → * C 2 , and C 2 is terminal, then (slice s C 1 ) ⇓ (slice s C 2 ).Now suppose that for a Wys source program, we prove in F a postcondition that the result is sealed alice n, for some n > 0. By the soundness of the ST semantics, we can conclude that when the program is run in the DS semantics, it may diverge, but if it terminates, alice's output will also be sealed alice n, and for all other principals their outputs will be sealed alice •.Aside from the correspondence on results, our semantics also covers correspondence on traces.Thus the correctness and security properties that we prove about a Wys program using F 's logic, hold for the program that actually runs.

Implementation
The formal semantics presented in the prior section is mechanized as an inductive type in F .This style is useful for proving properties, but does not directly translate to an implementation.Therefore, we implement an interpretation function step in F and prove that it corresponds to the rules; i.e., that for all input configurations C, step(C) = C implies that C → C according to the semantics.Then, the core of each principal's implementation is an F stub function tstep that repeatedly invokes step on the AST of the source program (produced by the F extractor run in a custom mode), unless the AST is an as sec node.Functions step and tstep are extracted to OCaml by the standard F extraction process.
Local evaluation is not defined for as sec, so the stub implements what amounts to P-enter and P-exit from Figure 5.When the stub notices the program has reached an as sec expression, it calls into a circuit library we have written that converts the AST of the second argument of as sec to a boolean circuit.This circuit and the encoded inputs are communicated to a co-hosted server that implements the GMW MPC protocol [22].The server evaluates the circuit, coordinating with the GMW servers of the other principals, and sends back the result.The circuit library decodes the result and returns it to the stub.The stub then carries on with the local evaluation.Our FFI interface currently provides a form of monomorphic, first-order interoperability between the (dynamically typed) interpreter and the host language.
Our F formalization of the Wys semantics, including the AST specification, is 1900 lines of code.This formalization is used both by the metatheory as well as by the (executable) interpreter.The metatheory that connects the ST and DS semantics ( §3) is 3000 lines.The interpreter and its correctness proof are another 290 lines of F code.The interpreter step function is essentially a big switch-case on the current expression, that calls into the functions from the semantics specification.The tstep stub is another 15 lines.The size of the circuit library, not including the GMW implementation, is 836 lines.The stub, the implementation of GMW, the circuit library, and F toolchain (including the custom Wys extraction mode) are part of our Trusted Computing Base (TCB).

Applications
In addition to joint median, presented in §2, we have implemented and proved properties of two other MPC applications, dealing for on-line card games and private set intersection (PSI).
Card dealing.We have implemented an MPC-based card dealing application in Wys .Such an application can play the role of the dealer in a game of online poker, thereby eliminating the need to trust the game portal for card dealing.The application relies on Wys 's support for secret shares [56].Using secret shares, the participating parties can share a value in a way that none of the parties can observe the actual value individually (each party's share consists of some random-looking bytes), but they can recover the value by combining their shares in sec mode.
In the application, the parties maintain a list of secret shares of already dealt cards (the number of already dealt cards is public information).To deal a new card, each party first generates a random number locally.The parties then perform a secure computation to compute the sum of their random numbers modulo 52, let's call it n.The output of the secure computation is secret shares of n.Before declaring n as the newly dealt card, the parties needs to ensure that the card n has not already been dealt.To do so, they iterate over the list of secret shares of already dealt cards, and for each element of the list, check that it is different from n.The check is performed in a secure computation that simply combines the shares of n, combines the shares of the list element, and checks the equality of the two values.If n is different from all the previously dealt cards, it is declared to be the new card, else the parties repeat the protocol by again generating a fresh random number each.
Wys provides the following API for secret shares: Type Sh α types the shares of values of type α.Our implementation currently supports shares of int values only; the can sh predicate enforces this restriction on the source programs.Extending secret shares support to other types (such as pairs) should be straightforward (as in [52]).Functions v of sh and ps of sh are marked Ghost, meaning that they can only be used in specifications for reasoning purposes.In the concrete code, shares are created and combined using the mk sh and comb sh functions.Together, the specifications of these functions enforce that the shares are created and combined by the same set of parties (through ps of sh), and that comb sh recovers the original value (through v of sh).The Wys interpreter transparently handles the low-level details of extracting shares from the GMW implementation of Choi et al. (mk sh), and reconstituting the shares back (comb sh).
In addition to implementing the card dealing application in Wys , we have formally verified that the returned card is fresh.The signature of the function that checks for freshness of the newly dealt card is as follows (abc is the set of three parties in the computation): val check fresh: l:list (Sh int){∀ s'.mem s' l =⇒ ps of sh s' = abc} → s:Sh int{ps of sh s = abc} → Wys bool (requires (fun m → m = Mode Par abc)) (ensures (fun r → r ⇐⇒ (∀ s'.mem s' l =⇒ not (v of sh s' = v of sh s)))) The specification says that the function takes two arguments: l is the list of secret shares of already dealt cards, and s is the secret shares of the newly dealt card.The function returns a boolean r that is true iff the concrete value (v of sh) of s is different from the concrete values of all the elements of the list l.Using F , we verify that the implementation of check fresh meets this specification.
PSI.Consider a dating application that enables its users to compute their common interests without revealing all of them.This is an instance of the more general private set intersection (PSI) problem [28].
We implement a straightforward version of PSI in Wys : where the input sets are expressed as lists with public lengths.Huang et al. [28] provide an optimized PSI algorithm that performs much better when the density of common elements in the two sets is high.We implement their algorithm in Wys .The optimized version consists of two nested loops -an outer loop for Alice's set and an inner loop for Bob's -where an iteration of the inner loop compares the current element of Alice's set with the current element of Bob's.The nested loops are written using as par so that both Alice and Bob execute the loops in lockstep (note that the set sizes are public), while the comparison in the inner loop happens using as sec.Instead of naive l a * l b comparisons, Huang et al. [28] observe that once an element of Alice's set ax matches an element of Bob's set bx, the inner loop can return immediately, skipping the comparisons of ax with the rest of Bob's set.Furthermore, bx can be removed from Bob's set, excluding it from any further comparisons with other elements in Alice's set.Since there are no repeats in the input sets, all the excluded comparisons are guaranteed to be false.We show the full code and its performance comparison with psi in Appendix A. As with the median example from §2, the optimized PSI intentionally reveals more for performance gains.As such, we would like to verify that the optimizations do not reveal more about parties' inputs.We take the following stepwise refinement approach.First, we characterize the trace of the optimized implementation as a pure function trace psi opt la lb (omitted for space reasons), and show that the trace of psi opt is precisely trace psi opt la lb.
Then, we define an intermediate PSI implementation that has the same nested loop structure, but performs l a * l b comparisons without any optimizations.We characterize the trace of this intermediate implementation as the pure function trace psi, and show that it precisely captures the trace.
To show that trace psi does not reveal more than the intersection of the input sets, we prove the following lemma.The lemma essentially says that for two runs on same length inputs, if the output is the same, then the resulting traces are permutation of each other. 6We can reason about the traces of psi interim up to permutation because Alice has no prior knowledge of the choice of representation of Bob's set (Bob can shuffle his list), so cannot learn anything from a permutation of the trace. 7This establishes the security of psi interim.
Finally, we can connect psi interim to psi opt by showing that there exists a function f, such that for any trace tr=trace psi la lb, the trace of psi opt, trace psi opt la lb, can be computed by f (length la) (length lb) tr.In other words, the trace produced by the optimized implementation can be computed using a function of information already available to Alice (or Bob) when she (or he) observes a run of the secure, unoptimized version psi interim la lb.As such, the optimizations do not reveal further information.

Related work
Source MPC verification.While the verification of the underlying crypto protocols has received some attention [4,5], the verification of correctness and security properties of MPC source programs has remained largely unexplored, surprisingly so given that the goal of MPC is to preserve the privacy of secret inputs.The only previous work that we know of is Backes et.al. [9] who devise an applied pi-calculus based abstraction for MPC, and use it for formal verification.For an auction protocol that computes the min function, their abstraction comprises about 1400 lines of code.Wys , on the other hand, enables direct verification of the higher-level MPC source programs, and not their models, and in addition provides a partially verified toolchain.
Wysteria.Wys 's computational model is based on programming abstractions of a previous domain-specific language, Wysteria [52].Wys 's realization as an embedded DSL in F makes important advances.In particular, Wys (a) enhances the Wysteria semantics to include a notion of observable traces, and provides the novel capability to prove security and correctness properties about mixed-mode MPC source programs, (b) expands the programming constructs available by drawing on features and libraries of F , and (c) adds assurance via a (partially) proved-correct implementation.
Verified MPC toolchain.Almeida et al. [4] build a verified toolchain consisting of (a) a verified circuit compiler from (a subset of) C to boolean circuits, and (b) a verified implementation of Yao's [64] garbled circuits protocol for 2-party MPC.They use CompCert [36] for the former, and EasyCrypt [11] for the latter.These are significant advances, but there are several distinctions from our work.The MPC programs in their toolchain are not mixed-mode, and thus it cannot express examples like median opt and the optimized PSI.Their framework does not enable formal verification of source programs like Wys does.It may be possible to use other frameworks for verifying C programs (e.g.Frama-C [1]), but it is inconvenient as one has to work in the subset of C that falls in the intersection of these tools.Wys is also more general as it supports general nparty MPC; e.g., the card dealing application in §4 has 3 parties.Nevertheless, Wys may use the verified Yao implementation for the special case of 2 parties.
MPC DSLs and DSL extensions.In addition to Wysteria several other MPC DSLs have been proposed in the literature [14,17,27,29,34,37,39,48,49,52,55,60].Most of these languages have standalone implementations, and the (usability/scalability) drawbacks that come with them.Like Wys , a few are implemented as language extensions.Launchbury et al. [35] describe a Haskell-embedded DSL for writing low-level "share protocols" on a multi-server "SMC machine".OblivC [65] is an extension to C for two-party MPC that annotates variables and conditionals with an obliv qualifier to identify private inputs; these programs are compiled by source-to-source translation.The former is essentially a shallow embedding, and the latter is compiler-based; Wys is unique in that it combines a shallow embedding to support source program verification and a deep embedding to support a non-standard target semantics.Recent work [19,21] compiles to cryptographic protocols that include both arithmetic and boolean circuits; the compiler decides which fragments of the program fall into which category.It would be interesting work to integrate such a backend in Wys .
Mechanized metatheory.Our verification results are different from a typical verification result that might either mechanize metatheory for an idealized language [8], or might prove an interpreter or compiler correct w.r.t. a formal semantics [36]-we do both.We mechanize the metatheory of Wys establishing the soundness of the conceptual ST semantics w.r.t. the actual DS semantics, and mechanize the proof that the interpreter implements the correct DS semantics.
General DSL implementation strategies.DSLs (for MPC or other purposes) are implemented in various ways, such as by developing a standalone compiler/interpreter, or by shallow or deep embedding in a host language.Our approach bears relation to the approach taken in LINQ [42], which embeds a query language in normal C# programs, and implements these programs by extracting the query syntax tree and passing it to a provider to implement for a particular backend.Other researchers have embedded DSLs in verification-oriented host languages (e.g., Bedrock [13] in Coq [59]) to permit formal proofs of DSL programs.Low [51] is a shallow-embedding of a small, sequential, well-behaved subset of C in F that extracts to C using a F -to-C compiler.Low has been used to verify and implement several cryptographic constructions.Fromherz et al. [25] present a deep embedding of a subset of x64 assembly in F that allows efficient verification of assembly and its interoperation with C code generated from Low .They design (and verify) a custom VC generator for the deeply embedded DSL, that allows for the proofs of assembly crypto routines to scale.

Conclusions
This paper has presented Wys , the first DSL to enable formal verification of efficient source MPC programs as written in a full-featured host programming language, F .The paper presented examples such as joint median, card dealing, and PSI, and showed how the DSL enables their correctness and security proofs.Wys implementation, examples, and proofs are publicly available on Github at https://github.com/FStarLang/FStar/tree/stratified_last/examples/wysteria.
in the Appendix.By convention, any free variables in the type signatures are universally prenex quantified.Defining as sec in Wys .val as sec: ps:prins → f:(unit → Wys a pre post) → Wys a (requires (fun m → m=Mode Par ps ∧ pre (Mode Sec ps))) (ensures (fun m r tr → tr=[TMsg r] ∧ ∃t.post (Mode Sec ps) r t))) val as par: ps:prins → (unit → Wys a pre post) → Wys (sealed ps a) (requires (fun m → m.mode=Par ∧ ps ⊆ m.ps ∧ can seal ps a ∧ pre (Mode Par ps))) (ensures (fun m r tr → ∃t.tr=[TScope ps t] ∧ post (Mode Par ps) (unseal r) t))) val median: in a:sealed {a} (int * int) → in b:sealed {b} (int * int) → Wys int (requires (fun m → m = Mode Par {a, b})) ( * should be called in the Par mode * ) (ensures (fun m r tr → let in a, in b = unseal in a, unseal in b in (median pre in a in b =⇒ r = median of in a in b) ∧ ( * functional correctness * ) tr = [TMsg ra])) ( * trace is just the final value * ) let opt trace a b (x1, ) (y1, ) m = [ TMsg (x1 > y1); ( * observable from the first as sec * ) TScope {a} []; TScope {b} []; ( * observables from two local as par * ) TMsg m ] ( * observable from the final as sec * ) A trace will have four elements: output of the first as sec computation, two empty scoped traces for the two local as par computations, and the final output.Using this function, we prove correctness of median opt, thus: val median opt: in a:sealed {a} (int * int) → in b:sealed {b} (int * int) → Wys int (requires (fun m → m = Mode Par {a, b})) ( * should be called in the Par mode * ) (ensures (fun m r tr → let in a = unseal in a in let in b = unseal in b in (median pre in a in b =⇒ r = median of in a in b) ∧ ( * functional correctness * ) tr = opt trace a b in a in b m ( * opt trace precisely describes the observable trace * ) val median opt is secure for alice: a:prin → b:prin → in a1:(int * int) → in a2:(int * int) → in b:(int * int) ( * possibly diff a1, a2 * ) → Lemma (requires (median pre in a1 in b ∧ median pre in a2 in b ∧ median of in a1 in b = median of in a2 in b)) ( * but same median * ) (ensures (opt trace a b in a1 in b (median of in a1 in b) = ( * ensures .. * ) opt trace a b in a2 in b (median of in a2 in b))) ( * .. same trace * )

Fig. 7 .
Fig. 7. Time to run (in secs) normal and optimized PSI for varying per-party set sizes and intersection densities.