MPC and HEIR #224
Replies: 8 comments 9 replies
-
I'm going to sketch out some ideas here as MLIR pseudocode We probably want to have different representations of the protocol as a whole vs the operations done by each participant (if/whether MPC is always symmetric I'm not sure) Maybe a protocol could start with secret representing what data is secret and what ops need to be computed on secret data. (not sure if the type below should be func.func @mpc_computation(%input : !secret.secret<tensor<1000xi32>>) {
%linear_layer = secret.generic
ins(%weights, %input : tensor<1000x256xi32>, !secret.secret<tensor<1000xi32>>) {
^bb0(%plain_weights: tensor<1000x256xi32>, %plain_input: tensor<1000xi32>) :
%0 = linalg.matmul %plain_input, %weights : tensor<256xi32>
secret.yield %0 : tensor<256xi32>
}
%relu_activation = secret.generic
ins(%layer1 : !secret.secret<tensor<256xi32>>) {
^bb0(%plain_layer1: tensor<256xi32>) :
%0 = some_dialect.relu %plain_layer1 : tensor<256xi32>
secret.yield %0 : tensor<256xi32>
}
func.return %relu_activation
} Secret here can be used to express that all servers involved are unaware the contents of the secret, i.e., they receive only shares. Then a pass could lower this to something like this, where module attributes {mpc.party_count = 3} {
func.func @mpc_computation_server_0(%input : tensor<1000x!secret.secret<i32, 0>>) {
<some ops...>
}
func.func @mpc_computation_server_1(%input : tensor<1000x!secret.secret<i32, 1>>) {
<some ops...>
}
// Maybe this server needs no input because its role in the protocol is to generate beaver triples
// Main point here is that the contents of each server's role can be asymmetric
func.func @mpc_computation_server_2() {
<some ops...>
}
} Here "secret" is semantically interpreted as a single share, private to one server unless they choose to reveal it. The ops inside these functions would need to be able to support low-level MPC ops like addition of two shares, addition and multiplication by a static constant and "opening" a share to its plaintext value, given enough shares. So these would be something like: shamir.add %0, %1 : (!secret.secret<i32, 0>, !secret.secret<i32, 0>) -> !secret.secret<i32, 0>
shamir.add_plaintext %0, %1 : (!secret.secret<i32, 0>, i32) -> !secret.secret<i32, 0>
shamir.reconstruct %2, %3, %4 (!secret.secret<i32, 0>, !secret.secret<i32, 1>, !secret.secret<i32, 2>) -> i32 In the last one, we're assuming that the threshold for recovering a secret from its shares is 3, and that an op verifier would require that the There would also need to be a way to construct shares, especially shares consisting of random numbers as used in beaver triples: %0 = arith.constant 5 : i32
%1 = shamir.split %0 {shares=3} : i32 -> (!secret.secret<i32, 0>, !secret.secret<i32, 1>, !secret.secret<i32, 2>) One would also need a mechanism to communicate, like mpc.broadcast %0 : !secret.secret<i32, 0>
mpc.send %0 {recipient=1} : !secret.secret<i32, 0> -> ()
mpc.receive {recipient=1} : () -> !secret.secret<i32, 1> I think there's a bit of delicacy here in reusing %0 = random.rand_int : i32
%s0, %s1 = shamir.split %0 {shares=2} : i32 -> (!secret.secret<i32, 0>, !secret.secret<i32, 1>)
mpc.send %s0 {recipient=0}: !secret.secret<i32, 0> -> ()
mpc.send %s1 {recipient=1}: !secret.secret<i32, 0> -> () The optimizations could come in:
The next step IMO is to pick a layer at which we want to demonstrate some interesting optimization can occur. |
Beta Was this translation helpful? Give feedback.
-
This is a great topic! Combining FHE+MPC(+ZKP) exponentially increases the range of applications for which we can achieve practical solutions, but it also exponentially increases the complexity of designing these solutions. I think there's more than enough here to have an entire meeting/WG session just dedicated to this topic. Note that secret sharing makes up only one half of the MPC world, with the other being Garbled Circuit-based approaches. Kind of like the LWE/RLWE split in FHE, one's better at arithmetic (secret sharing) and one's better at arbitrary binary things (GC). Also note, that Shamir secret sharing is only one approach to secret-sharing-based MPC, and there are others (e.g., additive secret sharing). There's a lot of prior art in this space and I might provide a more complete/curated reading list at some point, but for now I'll just throw out some keywords/things to look at:
|
Beta Was this translation helpful? Give feedback.
-
Like Alex mentioned above, even describing secret sharing has other axes (shamir vs additive) and also threshold values that can make the reconstruction parameters different. Obviously starting with one style of lowering is better. There's also a lot of prior MPC + compiler work, one of which is https://ieeexplore.ieee.org/document/9797347 (developing cost models for MPC) and Silph (https://eprint.iacr.org/2023/060). |
Beta Was this translation helpful? Give feedback.
-
I came across this interesting paper that characterizes the inefficiencies in PI schemes (hybrid or not): https://arxiv.org/abs/2207.07177 Something to note is that the networks are much larger (Res-Net 18, with 150 layers), but come with even higher bandwidth and storage costs than FHE (~50G / inference) and, depending on the request rate (e.g., 1 request per 15 minutes), the inference latency can take up to 30 minutes. |
Beta Was this translation helpful? Give feedback.
-
I was also looking around at possible MPC backends: https://github.com/rdragos/awesome-mpc#frameworks This interesting project has implementations in a bunch of these libraries: https://github.com/MPC-SoK/frameworks |
Beta Was this translation helpful? Give feedback.
-
Just pointing out a few things as I go:
|
Beta Was this translation helpful? Give feedback.
-
A small update: I was able to get TinyGarble to work with some of our existing boolean circuits, resulting in an inference on a small neural network (350k boolean gates, roughly half of them nands) in about 0.1s on my local machine. |
Beta Was this translation helpful? Give feedback.
-
TIL that Intel Labs has TinyGarble2: https://github.com/IntelLabs/TinyGarble2.0 @AlexanderViand-Intel maybe there's interest in integrating it? Interestingly, the paper for this project has a Google contributor who is on my current team: Baiyu Li |
Beta Was this translation helpful? Give feedback.
-
There's been some chatter internally at Google around MPC applications and compilers. I have mentioned in a few talks recently that we want the work in HEIR to also be useful in these settings, and so this thread is intended to be a place to discuss some of the details of what could be possible, either by extending the
secret
dialect in a way that is useful for both MPC and FHE, or else by having a new dialect with passes that can apply to both.For some context (and please correct me if I'm wrong, I'm only learning about MPC's details right now), MPC seems to be based on Shamir secret sharing over a finite ring of coefficients. Each participating party gets one share
[x]_i
of a secret valuex
, uses the partial homomorphism of Shamir's scheme to locally compute things like[x+y]_i
from[x]_i
and[y]_i
, but requires complex communication protocols (and/or pre-computed random shares like "Beaver triples") to compute other things.The main areas of MPC protocol research appears to be
I don't think HEIR will contribute much to the first one, but the second and third are plausible. While some of these could be peephole optimizations, it seems more likely that one would need to do some sort of optimization/synthesis, wherein a global analysis of the protocol runs with a cost model representing communication complexity, though there are some primitives like the RELU function in SecureNN 1 that this could apply to at a smaller scale.
Beta Was this translation helpful? Give feedback.
All reactions