Wysteria: A Programming Language for Generic, Mixed-Mode Multiparty Computations Aseem Rastogi Matthew Hammer, Michael Hicks (University of Maryland, College Park)
What is Secure Multiparty Computation (SMC) A B Compute f(A, B) Without revealing A to Bob and B to Alice
Using a Trusted Third Party A B A B f(A, B) Compute f(A, B) Without revealing A to Bob and B to Alice
SMC Eliminates Trusted Third Party A B Compute f(A, B) Without revealing A to Bob and B to Alice Cryptographic Protocol
SMC Examples Private Data Nearest neighborLocations AuctionBids Private set intersectionSets Statistical computationNumbers
Beyond Toy SMC Examples Online card games SMC to deal cards Dice-based games SMC to roll dice
Monolithic Secure Multiparty Computation f(A, B) A B Not Enough !
Mixed-Mode Secure Multiparty Computation f(A, B) A B g(A 1, B 1 ) A 1 B 1 g(A 1, B 1 ) … … h(A 2, B 2 ) A 2 B 2 h(A 2, B 2 ) … Local … Secure State
State Of The Art: Existing SMC Languages Fairplay, FairplayMP, CBMC-GC – Only “circuit compilers” – No mixed-mode – No secure state L1 – Only 2-party, low level – No formal guarantees FastGC – Circuit library, only 2-party None supports generic programs (parametric in number of parties) None supports generic programs (parametric in number of parties)
Our Goal Push SMC beyond toy applications
Design an SMC Language Local and secure computations High-level support for secure state Mixed-Mode Code parametric in number of parties Generic Single specification Runtime compilation to circuits High-level Statically typed, sound Compositional Guarantees
A High-level Functional Language to write Mixed-Mode Generic SMCs Implementation and examples available at: Developing Online Poker using Wysteria (almost there …) Goes Without Saying, Wysteria Has It All ! Demo (coming up) Demo (coming up)
Wysteria by Examples: Two-party Millionaire’s * let a = read() in let b = read() in let o = a > b in o par(A) par(B) sec(A,B) *The example in this form does not type check in Wysteria. Single specification A and B run the same program Compute who is richer among A and B
Wysteria by Examples: Two-party Millionaire’s let a = read() in let b = read() in let o = a > b in o par(A) par(B) sec(A,B) A’s Local Computation (Skipped by B) Computation modes
Wysteria by Examples: Two-party Millionaire’s let a = read() in let b = read() in let o = a > b in o par(A) par(B) sec(A,B) A’s Local Computation B’s Local Computation (Skipped by A)
Wysteria by Examples: Two-party Millionaire’s let a = read() in let b = read() in let o = a > b in o par(A) par(B) sec(A,B) A’s Local Computation B’s Local Computation Secure Computation by (A,B)
let a = read() in let b = read() in let o = a > b in o par(A) par(B) sec(A,B) A’s Local Computation B’s Local Computation Secure Computation by (A,B) Runtime compiles it to boolean circuit, and evaluates using secure computation No communication primitives ! Wysteria by Examples: Two-party Millionaire’s
Key Ideas Mixed-Mode Computations via Mode Annotations
Wysteria by Examples: Asymmetric Output let a = read() in let b = read() in let o = a > b in o par(A) par(B) sec(A,B) What if only A is allowed to know the output ?
Wysteria by Examples: Asymmetric Output let a = read() in let b = read() in let o = wire A:(a > b) in o par(A) par(B) sec(A,B) What if only A is allowed to know the output ? Wire Bundle
Wire Bundles in Wysteria Maps from parties to values Each party sees only its own component in the bundle – Or nothing if it’s not in the domain Wire bundles are dependently typed Create wire A:0 : W {A} nat Concat (wire A:0)++(wire B:1) : W {A U B} nat Project (wire A:0)[A] : nat
Wysteria by Examples: Inputs Via Wire Bundles let a = read() in let b = read() in let w1 = wire A:a in let w2 = wire B:b in let w3 = w1 ++ w2 in let o = wire A:(w3[A] > w3[B]) in o par(A) par(B) sec(A,B)
let a = read() in let b = read() in let w1 = wire A:a in let w2 = wire B:b in let w3 = w1 ++ w2 in let o = wire A:(w3[A] > w3[B]) in o Wysteria by Examples: Wire Bundle Views A’s ViewB’s Viewsec(A,B)’s View w1{A:a}{}{A:a} w2{}{B:b} w3{A:a}{B:b}{A:a,B:b} par(A) par(B) sec(A,B)
Key Ideas Wire Bundle Abstraction for Private Inputs/Outputs Mixed-Mode Computations via Place Annotations
let mill = λx:W {A U B} nat. let o = x[A] > x[B] in o in let a = read () in let b = read () in mill (wire A:a ++ wire B:b) sec(A,B) Wysteria by Examples: Functions par(A) par(B)
So Far We Have Seen … Mixed-Mode support via mode annotations Wire Bundles abstraction for private data Now: Writing Generic Code in Wysteria
Parties As First Class Values Parties are values of type ps φ Refinement types for more precise invariants {A} : ps {ν = A} {A} : ps {ν A U B}
Wysteria by Examples: Generic Millionaire’s sec(x) let comb = λx:ps. λy:W x nat. λa:ps option. λp:ps. λn:nat match a with | None => Some(p) | Some(q) => if y[q] > n then a else Some(p) in let mill = λx:ps. λy:W x nat. let o = wfold(y, None, comb x y) in o in … sec(x)
Wysteria by Examples: Generic Millionaire’s sec(x) let comb = λx:ps. λy:W x nat. λa:ps option. λp:ps. λn:nat match a with | None => Some(p) | Some(q) => if y[q] > n then a else Some(p) in let mill = λx:ps. λy:W x nat. let o = wfold(y, None, comb x y) in o in … sec(x)
Wysteria by Examples: Generic Millionaire’s sec(x) let comb = λx:ps. λy:W x nat. λa:ps{ν x} option.λp:ps{ν x}.λn:nat match a with | None => Some(p) | Some(q) => if y[q] > n then a else Some(p) in let mill = λx:ps. λy:W x nat. let o = wfold(y, None, comb x y) in o in … sec(x)
Key Ideas Generic Code: 1. Parties as First Class Values 2. Wire Bundle Combinators (e.g. wfold ) Wire Bundle Abstraction for Private Inputs/Outputs Mixed-Mode Computations via Place Annotations
Wysteria Metatheory Formalized using λ -calculus with extensions Dependent type system Two operational semantics: – Single-threaded (SIMD style specification) – Multi-threaded (actual protocol runs) – Slicing judgment from single- to multi-threaded
Wysteria Theorems* Type soundness (progress and preservation) in single-threaded semantics Sound simulation: C1C1 C2 π1π1 π2π2 … * Single-threaded Multi-threaded slice operation *Proofs in Technical Report
Wysteria Implementation We use GMW Implementation from Choi et. al.
Wysteria Evaluation Applicationn-Party ?Mixed-Mode ?Secure state ? Millionaire’sYesNo 2 nd Price auctionYesNo PSI2-partyYesNo Nearest neighborYesNo Median2-partyYesNo PSI count2-partyYes 2-round biddingYes Online pokerYes
Wysteria Code for Card Dealing let retryloop = fix retryloop: (tmp5:unit) -> W tgt nat. (tmp5:unit). let myrand = \(z:unit).rand () in let rs = wapp x [wire x:(); wire x:myrand] in let res = check rs in if res.#success then let nd = select ndealt[0] in let _ = update dealt [nd] <- res.#sum in let _ = update ndealt [0] <- nd + 1 in let sec(x) = let s = combsh (res.#sum) in wire tgt:s in card else retryloop () in retryloop () in wcopy as x from w in { #deal : deal } in Secure computation Local computation Secret shares let rand = \(myunit:unit). sysop rand 52 in let mkdeal = \(x:ps{true}). let par(x) = let sec(x) = makesh 0 in zerosh1 in let par(x) = array [ 52 ] of zerosh in let par(x) = array [ 1 ] of 0 in let deal = \(tgt:ps{singl and subeq x}). let par(x) = let check = \(rs:W x nat). let nd = select ndealt[0] in let sec(x) = let s = wfold x [rs; 0; \(n1:nat).\(p:ps{true}).\(n2:nat). n1 + n2 ] in let s1 = wfold x [wire x:(); s; \(n1:nat).\(p:ps{true}).\(n2:unit). if n1 > 51 then n else n1 ] in makesh s1 in let checkloop = fix checkloop:(i:nat) -> {#sum:Sh x nat, #success: bool}. (i:nat). if i = nd then {#sum:sum, #success:true} else l2et sd = select dealt[i] in let sec(x) = let t1 = combsh sd in let t2 = combsh sum in t1 = t2 in if cmp then {#sum:sum, #success:false} else checkloop (i + 1) n checkloop 0 in
Demo (Card dealing using Wysteria) Future Work: Integrate with bitcoin for betting (c.f. Secure Multiparty Computation on BitCoin, Andrychowicz et. al.)
Also In The Paper … Support for secure state More language features – Mutable state (interesting interaction with mixed- mode) – Additional wire bundle combinators Performance evaluation Complete proofs in TR
Wysteria Summary Implementation and examples available at: A High-level Functional Language to write Mixed-Mode Generic SMCs