Skip to content
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

Sql like demos #149

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion demos/run-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ if [ "$1" == "*" ]; then
EXIT_CODE=0
for i in demos/*; do
if [ -f "$i/test.js" ]; then
if ! [[ "$i" =~ ^demos/(pca|mpc-web|template|mpc-as-a-service)$ ]]; then
if ! [[ "$i" =~ ^demos/(pca|restAPI|template|mpc-as-a-service)$ ]]; then
sleep 2
npm run-script test-demo -- "$i"
CODE=$?
Expand Down
21 changes: 13 additions & 8 deletions lib/jiff-client.js
Original file line number Diff line number Diff line change
Expand Up @@ -859,14 +859,19 @@
jiff.emit(share_id + 'length', receivers_list, array.length.toString(10));
}

jiff.listen(share_id + 'length', function (sender, message) {
lengths[sender] = parseInt(message, 10);
total++;
if (total === senders_list.length) {
jiff.remove_listener(share_id + 'length');
share_array_deferred.resolve(lengths);
}
});
if (receivers_list.indexOf(jiff.id) > -1) {
jiff.listen(share_id + 'length', function (sender, message) {
lengths[sender] = parseInt(message, 10);
total++;
if (total === senders_list.length) {
jiff.remove_listener(share_id + 'length');
share_array_deferred.resolve(lengths);
}
});
} else if (senders_list[0] === jiff.id && senders_list.length === 1) {
lengths[jiff.id] = array.length;
share_array_deferred.resolve(lengths);
}
} else if (typeof(lengths) === 'number') {
// All arrays are of the same length
var l = lengths;
Expand Down
2 changes: 1 addition & 1 deletion lib/jiff-server.js
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ exports.make_jiff = function (http, options) {
};

jiff.custom = function (computation_id, from_id, msg) {
jiff.hooks.log(jiff, 'custom from ' + computation_id + '-' + from_id + ' : ' + msg);
jiff.hooks.log(jiff, 'custom from ' + computation_id + '-' + from_id + ' : ' + JSON.stringify(msg));

try {
msg = jiff.execute_array_hooks('beforeOperation', [jiff, 'custom', computation_id, from_id, msg], 4);
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"jsdoc": "^3.5.5",
"marked": "^0.3.9",
"minimist": "^1.2.0",
"mocha": "^4.0.1"
"mocha": "^4.0.1",
"nunjucks": "^3.1.7"
}
}
52 changes: 52 additions & 0 deletions presentation/least-squares/analyst/analyst.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<!-- Basic UI for running the demo in the browser -->

<html>
<head>
<title>Linear Least Squares</title>
<style>
.error {
color: #FF0000;
}

td, th {
border: solid 1px darkgray;
}

th input, td input {
width: 70px;
}
</style>

<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.min.js"></script>

<script src="/socket.io/socket.io.js"></script>
<script src="/bignumber.js/bignumber.min.js"></script>
<script src="/lib/sodium.js"></script>
<script src="/lib/jiff-client.js"></script>
<script src="/lib/ext/jiff-client-bignumber.js"></script>
<script src="/lib/ext/jiff-client-fixedpoint.js"></script>
<script src="/lib/ext/jiff-client-negativenumber.js"></script>

<!-- Contains UI Handlers and Input Checks -->
<script type="text/javascript" src="/static/analyst/analyst.js"></script>

<!-- Contains the MPC implementation -->
<script type="text/javascript" src="/static/analyst/mpc.js"></script>
</head>
<body>
<h1>Analyst</h1>
<h3>Analysis:</h3> <button onclick="submit();" id="submit">Linear Least Squares</button>
<br/>
<h3>Output:</h3>
<div id="output" style="display: none;">
<div style="width:900px; height:900px;">
<canvas id="myChart" width="900" height="900"></canvas>
</div>
</div>
</body>

<script type="text/javascript">
connect({{config.compute + 1}}, {{config.total}}, {{config.compute}}, '{{ config.computation_id }}');
</script>
</html>
103 changes: 103 additions & 0 deletions presentation/least-squares/analyst/analyst.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/**
* Do not modify this file unless you have to.
* This file has UI handlers.
*/

// eslint-disable-next-line no-unused-vars
var computes = [];
function connect(party_id, party_count, compute_count, computation_id) {
// Compute parties ids
for (var c = 1; c <= compute_count; c++) {
computes.push(c);
}

// jiff options
var options = { party_count: party_count, party_id: party_id };
options.onError = function (error) {
$('#output').append('<p class=\'error\'>'+error+'</p>');
};
options.onConnect = function () {
$('#output').append('<p>Connected!</p>');
};

// host name
var hostname = window.location.hostname.trim();
var port = window.location.port;
if (port == null || port === '') {
port = '80';
}
if (!(hostname.startsWith('http://') || hostname.startsWith('https://'))) {
hostname = 'http://' + hostname;
}
if (hostname.endsWith('/')) {
hostname = hostname.substring(0, hostname.length-1);
}
if (hostname.indexOf(':') > -1 && hostname.lastIndexOf(':') > hostname.indexOf(':')) {
hostname = hostname.substring(0, hostname.lastIndexOf(':'));
}

hostname = hostname + ':' + port;

// eslint-disable-next-line no-undef
mpc.connect(hostname, computation_id, options, computes, function (id, cols) {
var schema = 'Party ' + (id - computes.length - 1) + ': ' + cols.join(' | ') + '<br/>';
document.getElementById('schema').innerHTML += schema;

Check failure on line 44 in presentation/least-squares/analyst/analyst.js

View check run for this annotation

Codacy Production / Codacy Static Code Analysis

presentation/least-squares/analyst/analyst.js#L44

User controlled data in methods like `innerHTML`, `outerHTML` or `document.write` is an anti-pattern that can lead to XSS vulnerabilities
});
}

// eslint-disable-next-line no-unused-vars
function submit() {
$('#output').append('<p>Starting...</p>');
$('#submit').attr('disabled', true);

// eslint-disable-next-line no-undef
mpc.compute().then(plot);
}

/**
* Helpers for drawing lines in a chart
*/
// The limits of the graph. The minimum and maximum X and Y values.
var minX = -60;
var maxX = 60;
var minY = -60;
var maxY = 60;

// Chart for drawing
function initChart(line) {
var ctx = document.getElementById('myChart').getContext('2d');

var scales = {
yAxes: [{ ticks: { min: minY, max: maxY, maxTicksLimit: 5 } }],
xAxes: [{ type: 'linear', position: 'bottom', ticks: { min: minX, max: maxX, maxTicksLimit: 20 } }]
};

// eslint-disable-next-line no-undef
var myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{ id: 'least-line', label: '', data: line, fill: false, pointBackgroundColor: '#000099', borderColor: '#000099', pointRadius: 0 }
]
},
options: {
elements: { line: { tension: 1 } },
scales: scales
}
});
myChart.update();
}

function plot(data) {
console.log(data.slope.toString(), data.yIntercept.toString());
var m = data.slope;
var p = data.yIntercept;

var points = [];
for (var i = minX; i <= maxX; i+=1) {
points.push({x: i, y: m.times(i).plus(p).toNumber()});
}

$('#output').show();
initChart(points);
}
36 changes: 36 additions & 0 deletions presentation/least-squares/analyst/mpc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
(function (exports) {
var jiff_instance;
var computes;

/**
* Connect to the server and initialize the jiff instance
*/
exports.connect = function (hostname, computation_id, options, _computes, schema_callback) {
computes = _computes;
var opt = Object.assign({}, options);
opt.Zp = '4503599627370449';
opt.integer_digits = 9;
opt.decimal_digits = 3;

// eslint-disable-next-line no-undef
jiff_instance = jiff.make_jiff(hostname, computation_id, opt);
// eslint-disable-next-line no-undef
jiff_instance.apply_extension(jiff_bignumber, opt);
// eslint-disable-next-line no-undef
jiff_instance.apply_extension(jiff_fixedpoint, opt);
// eslint-disable-next-line no-undef
jiff_instance.apply_extension(jiff_negativenumber, opt);
};

/**
* The MPC computation
*/
exports.compute = function () {
var promise1 = jiff_instance.receive_open(computes);
var promise2 = jiff_instance.receive_open(computes);

return Promise.all([promise1, promise2]).then(function (res) {
return {slope: res[0], yIntercept: res[1]};
});
};
}(this.mpc = {}));
96 changes: 96 additions & 0 deletions presentation/least-squares/compute/mpc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Configurations
var decimal_digits = 3;

var config = require('../config.json');
var computes = [];
for (var c = 1; c <= config.compute; c++) {
computes.push(c);
}
var analyst = computes.length + 1;
var inputs = [];
for (var i = config.compute + 2; i <= config.total; i++) {
inputs.push(i);
}

/**
* Connect to the server and initialize the jiff instance
*/
exports.connect = function (hostname, computation_id, options) {
var opt = Object.assign({}, options);
opt.Zp = '4503599627370449';
opt.integer_digits = 9;
opt.decimal_digits = decimal_digits;

var jiff = require('../../../lib/jiff-client');
var jiff_bignumber = require('../../../lib/ext/jiff-client-bignumber');
var jiff_fixedpoint = require('../../../lib/ext/jiff-client-fixedpoint');
var jiff_negativenumber = require('../../../lib/ext/jiff-client-negativenumber');

var jiff_instance = jiff.make_jiff(hostname, computation_id, opt);
jiff_instance.apply_extension(jiff_bignumber, opt);
jiff_instance.apply_extension(jiff_fixedpoint, opt);
jiff_instance.apply_extension(jiff_negativenumber, opt);
jiff_instance.wait_for(computes, function () {
compute(jiff_instance);
});
jiff_instance.wait_for(['s1'], function () {
console.log('This is compute party ', jiff_instance.id);
})
};

/**
* The MPC computation
*/
function compute(jiff_instance) {
var avgs = jiff_instance.share(null, computes.length, computes, inputs);
var xAvg = avgs[inputs[0]];
var yAvg = avgs[inputs[1]];

var xBar = jiff_instance.share_array([], null, computes.length, computes, [inputs[0]]);
var yBar = jiff_instance.share_array([], null, computes.length, computes, [inputs[1]]);
xBar.then(function (arr) {
console.log('First input party secret shared their data!');
var share = arr[inputs[0]][0];
if (share.value != null) {
console.log('First secret share value ', share.value.toString());
} else {
share.promise.then(function () {
console.log('First secret share value ', share.value.toString());
});
}
});
yBar.then(function (arr) {
console.log('Second input party secret shared their data!');
var share = arr[inputs[1]][0];
if (share.value != null) {
console.log('First secret share value ', share.value.toString());
} else {
share.promise.then(function () {
console.log('First secret share value ', share.value.toString());
});
}
});

var xBarSquare = jiff_instance.share(null, computes.length, computes, [inputs[0]])[inputs[0]];

Promise.all([xBar, yBar]).then(function (res) {
xBar = res[0][inputs[0]];
yBar = res[1][inputs[1]];

var numerator = xBar[0].smult(yBar[0], null, false);
for (var i = 1; i < xBar.length; i++) {
numerator = numerator.sadd(xBar[i].smult(yBar[i], null, false));
}
var denumerator = xBarSquare.cmult(jiff_instance.helpers.magnitude(decimal_digits));

// Compute slope and y Intercept of line
var slope = numerator.sdiv(denumerator);
var yIntercept = yAvg.ssub(slope.smult(xAvg, 'main-smult'));

// Done
jiff_instance.wait_for([analyst], function () {
jiff_instance.open(slope, [analyst]);
jiff_instance.open(yIntercept, [analyst]);
});
});
}
16 changes: 16 additions & 0 deletions presentation/least-squares/compute/party.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/**
* Do not change this unless you have to.
* This code parses input command line arguments,
* and calls the appropriate initialization and MPC protocol from ./mpc.js
*/
var mpc = require('./mpc');
var config = require('../config.json');

// JIFF options
var options = {
initialization: {role: 'compute'},
party_count: config.total
};

// Connect
mpc.connect('http://localhost:8080', config.computation_id, options);
5 changes: 5 additions & 0 deletions presentation/least-squares/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"computation_id": "test",
"compute": 2,
"total": 5
}
Loading