-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support For-Each-Join Loops #133
Conversation
Garble automatically joins the arrays in a for-each-join loop using a [bitonic sorting network](https://en.wikipedia.org/wiki/Bitonic_sorter), more concretely implementing the paper [Private Set Intersection: | ||
Are Garbled Circuits Better than Custom Protocols?](https://www.ndss-symposium.org/wp-content/uploads/2017/09/06_4.pdf), which has a circuit complexity of `(m + n) * log(m + n)` instead of `m * n` which would result from joining the arrays using nested loops. **The arrays that are joined in the loop must be sorted**, otherwise elements might be discarded or invalid data returned. | ||
|
||
For-each-join loops always join two arrays based on the first field. If you would like to compare more than one field for equality, the easiest way is to transform the sorted array so that the relevant fields are grouped together in a tuple and thus form the first field. Such a transformation will be completely optimized away by the Garble compiler, such as in the following example, which groups together the first two fields, compiled to a circuit with 0 gates: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it then only input and output wires or you mean 0 AND gates here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Based on the assert in the test case I assume this should be 0 AND gates.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
0 AND gates but also only 2 XOR gates (which are always included in circuits to get constant 0 and 1), so basically no intermediate gates.
@@ -993,6 +998,39 @@ impl CircuitBuilder { | |||
} | |||
(acc_lt, acc_gt) | |||
} | |||
|
|||
pub fn push_condswap( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checked this conditional swap, this is great (the solution that requires only one AND gate)!
(x_swapped, y_swapped) | ||
} | ||
|
||
pub fn push_sorter( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I get it right this is what is shown in the paper in Figure 2c as 2Sorter. Looks good!
language_tour.md
Outdated
``` | ||
|
||
Garble automatically joins the arrays in a for-each-join loop using a [bitonic sorting network](https://en.wikipedia.org/wiki/Bitonic_sorter), more concretely implementing the paper [Private Set Intersection: | ||
Are Garbled Circuits Better than Custom Protocols?](https://www.ndss-symposium.org/wp-content/uploads/2017/09/06_4.pdf), which has a circuit complexity of `(m + n) * log(m + n)` instead of `m * n` which would result from joining the arrays using nested loops. **The arrays that are joined in the loop must be sorted**, otherwise elements might be discarded or invalid data returned. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What we could also add is that we do not do the shuffle step of their protocol as the join is intended to be used further in computation. But if someone only would want to do join and reveal the result that would still need to be implemented?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point, I updated it slightly.
I couldn't really follow the details of the implementation, but it looks really good to me! Communication-wise it's also quite clear how it should be used! |
This PR implements support for joining together two (sorted) arrays of tuples efficiently, using a bitonic sorting network.
The feature is best explained in the language tour: