-
Notifications
You must be signed in to change notification settings - Fork 51
/
mpc.js
126 lines (103 loc) · 3.5 KB
/
mpc.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
(function (exports, node) {
var saved_instance;
/**
* Connect to the server and initialize the jiff instance
*/
exports.connect = function (hostname, computation_id, options) {
var opt = Object.assign({}, options);
// Added options goes here
if (node) {
// eslint-disable-next-line no-undef
jiff = require('../../lib/jiff-client');
// eslint-disable-next-line no-undef,no-global-assign
$ = require('jquery-deferred');
}
// eslint-disable-next-line no-undef
saved_instance = jiff.make_jiff(hostname, computation_id, opt);
exports.saved_instance = saved_instance;
// if you need any extensions, put them here
return saved_instance;
};
exports.compute = function (input, jiff_instance) {
if (jiff_instance == null) {
jiff_instance = saved_instance;
}
var final_deferred = $.Deferred();
var final_promise = final_deferred.promise();
// Share the arrays
jiff_instance.share_array(input, input.length).then(function (shares) {
// sum all shared input arrays element wise
var array = shares[1];
for (var p = 2; p <= jiff_instance.party_count; p++) {
for (var i = 0; i < array.length; i++) {
array[i] = array[i].sadd(shares[p][i]);
}
}
// shuffle new array
var shuffled = shuffle(array, jiff_instance);
// Open the array
var allPromises = [];
for (var k = 0; k < shuffled.length; k++) {
allPromises.push(jiff_instance.open(shuffled[k]));
}
Promise.all(allPromises).then(function (results) {
final_deferred.resolve(results);
});
});
return final_promise;
};
function shuffle(array, jiff_instance) {
var result = [];
for (var i = array.length-1; i > 0; i--) {
array = array.slice(0, i+1);
var bits = jiff_instance.protocols.bits.rejection_sampling(0, i+1);
var random = jiff_instance.protocols.bits.bit_composition(bits);
array = binary_swap(array, random, array[i]);
// swap element found into last position of array
var tmp = array[1];
array = array[0];
array[i] = tmp;
result[i] = array[i];
}
result[0] = array[0];
return result;
}
function search_and_swap(array, random, i) {
for (var j = 0; j < array.length; j++) {
var c1 = array[j];
var cmp = random.ceq(j);
array[j] = cmp.if_else(array[i], c1);
array[i] = cmp.if_else(c1, array[i]);
}
return array;
}
function binary_swap(array, element, last) {
if (array.length === 1) {
var tmp = array[0];
array[0] = last;
return [array, tmp];
}
// comparison
var mid = Math.floor(array.length/2);
var cmp = element.clt(mid);
// Slice array in half, choose slice depending on cmp
var nArray = [];
for (var i = 0; i < mid; i++) {
var c1 = array[i];
var c2 = array[mid+i];
nArray[i] = cmp.if_else(c1, c2);
}
// watch out for off by 1 errors if length is odd.
if (2*mid < array.length) {
nArray[mid] = array[2*mid];
}
// change element to search for depending on array split decision
element = cmp.if_else(element, element.csub(mid));
var result = binary_swap(nArray, element, last);
for (var i = 0; i < mid; i++) {
array[i] = cmp.if_else(result[0][i], array[i]);
array[mid+i] = cmp.if_else(array[mid+i], result[0][i]);
}
return [array, result[1]];
}
}((typeof exports === 'undefined' ? this.mpc = {} : exports), typeof exports !== 'undefined'));