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

[WIP] GMW share/open and XOR/AND bit operations #200

Closed
wants to merge 88 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
cb13e26
finish bmw share and open function
YuwanXiao Jun 8, 2020
a74011c
Small changes: Linting in files of BMW_demo, return promise to party.…
p-flock Jun 9, 2020
44f6c74
add test for bmw share and open
YuwanXiao Jun 10, 2020
0b0bb3e
add test for bmw share and open
YuwanXiao Jun 10, 2020
3c6c719
comment out console output
YuwanXiao Jun 10, 2020
8879c11
add test for gmw_xor and rename bmw to gmw
YuwanXiao Jun 16, 2020
86cc7b8
rename bmw to gmw
YuwanXiao Jun 16, 2020
062567d
rename bmw to gmw
YuwanXiao Jun 16, 2020
f9677bc
rename bmw to gmw
YuwanXiao Jun 16, 2020
8be7626
change dir name from bmw to gmw
YuwanXiao Jun 16, 2020
dc27178
remove duplicate dir
YuwanXiao Jun 16, 2020
1737173
update skeleton code for OT
YuwanXiao Jun 16, 2020
9327928
fix a require bug
YuwanXiao Jun 17, 2020
3a5c3df
OT implementation with single threaded test using emit and listen
YuwanXiao Jun 17, 2020
d03c1f1
extend to >2 GMW and function with test code
YuwanXiao Jun 19, 2020
e48c83a
update with only partcipating two party for debug test
YuwanXiao Jun 19, 2020
1b436a6
updated and among multiple party, parallel test hanging bug to fix
YuwanXiao Jun 19, 2020
def522c
adjust xor and finish parallel test for gmw_xor
YuwanXiao Jun 25, 2020
9edaeac
count bug with async listen
YuwanXiao Jun 29, 2020
514bf0b
Refactor GMW_XOR function to work similarly to secret addition:
p-flock Jun 29, 2020
8b8c4f2
Update GMW demo:
p-flock Jun 29, 2020
e5aefc1
and with ot function and test
YuwanXiao Jul 1, 2020
14e0cbe
delete unused file
YuwanXiao Jul 1, 2020
cc75748
delete unused file
YuwanXiao Jul 1, 2020
4ad8432
delete unused filr
YuwanXiao Jul 1, 2020
644da3d
delete unused file
YuwanXiao Jul 1, 2020
a5c0b2c
clean up log
YuwanXiao Jul 1, 2020
d5a9837
rename gmw_OT to gmw_and
YuwanXiao Jul 1, 2020
b451d80
clean up log and add document for functions
YuwanXiao Jul 1, 2020
b59c62a
to be update by new one
YuwanXiao Jul 1, 2020
4da71b5
delete gmw_OT
YuwanXiao Jul 1, 2020
1e7c3fd
Delete browser demo, no need
YuwanXiao Jul 2, 2020
d3d5e7d
delete browser demo, no need
YuwanXiao Jul 2, 2020
a0438cf
update readme and jsdoc formatting
YuwanXiao Jul 2, 2020
4decf0b
integrate with i-out-of-n lib,1. tag=0, and 2.overwritten resoving, 3…
YuwanXiao Jul 10, 2020
c6bd9ce
finish merging OT with i-out-of-n lib among multiparty
YuwanXiao Jul 16, 2020
8021f08
Delete example from 1-out-of-n lib
YuwanXiao Jul 16, 2020
6b3870c
delete ascii.js from 1-out-of-n lib
YuwanXiao Jul 16, 2020
b869f6e
delete index from 1-out-of-n lib
YuwanXiao Jul 16, 2020
72ff514
updating submodule
YuwanXiao Jul 16, 2020
f2a9788
Merge branch '197_GMW' of github.com:multiparty/jiff into 197_GMW
YuwanXiao Jul 16, 2020
ecde765
updating submodule
YuwanXiao Jul 16, 2020
632cb74
submodule update IO.js
YuwanXiao Jul 16, 2020
0b8bb9d
clean 1-out-of-n structure
YuwanXiao Jul 20, 2020
3809d09
delete submodule
YuwanXiao Jul 20, 2020
a7d6f6a
Remove a submodule.
YuwanXiao Jul 20, 2020
6228e1b
Remove a submodule.
YuwanXiao Jul 20, 2020
4840a6a
update op_id with ot.js
YuwanXiao Jul 21, 2020
c9687c7
merging share and open to lib
YuwanXiao Jul 21, 2020
53f9a3d
add missing event.js
YuwanXiao Jul 21, 2020
fb0f077
add missing file
YuwanXiao Jul 21, 2020
674c3e0
add dependency
YuwanXiao Jul 22, 2020
ffc23e6
add dependency
YuwanXiao Jul 22, 2020
902ebb0
add dependency
YuwanXiao Jul 22, 2020
2cb878f
code review adjustment
YuwanXiao Jul 22, 2020
c55fd16
merging to lib
YuwanXiao Jul 27, 2020
e6ec73d
update IO with updated generalized ot lib
YuwanXiao Jul 27, 2020
2912739
merge ot listen into lib
YuwanXiao Jul 28, 2020
7016b50
Add GMW suite to travis config
p-flock Jul 29, 2020
42f523d
add unit test for gmw
YuwanXiao Jul 29, 2020
bb3ef99
add missed file
YuwanXiao Jul 29, 2020
c2fcf14
adding browser version demo
YuwanXiao Jul 31, 2020
7d4bc51
update readme
YuwanXiao Jul 31, 2020
bdeb2ce
Merge branch 'master' into 197_GMW
p-flock Aug 7, 2020
9b2ef1e
Merge branch 'master' into 197_GMW
wyatt-howe Aug 10, 2020
2cd7ce0
fix array sharing require path
p-flock Aug 10, 2020
ed23049
Merge branch '197_GMW' of github.com:multiparty/jiff into 197_GMW
p-flock Aug 10, 2020
836a9f4
npm update
YuwanXiao Aug 11, 2020
4aa718b
original jiff-client
YuwanXiao Aug 11, 2020
1d06c01
adding package.json
YuwanXiao Aug 11, 2020
c217ce9
update npm version
YuwanXiao Aug 12, 2020
acfd138
Fix README.md in demos/ (#206) (#210)
p-flock Aug 12, 2020
5aeb436
recover API binding for jiff.open_ND_array()
p-flock Aug 12, 2020
7f6480a
testing and
YuwanXiao Aug 14, 2020
dbd50b9
test update
YuwanXiao Aug 14, 2020
8fc932d
Update jiff-client.js (do `npm run-script build`)
wyatt-howe Aug 23, 2020
0be7937
Rename `GMW_demo` to `GMW-protocol`
wyatt-howe Aug 23, 2020
dd8e1ee
Clean up GMW namespace and use encapsulation like the other protocols do
wyatt-howe Aug 23, 2020
d82eabd
backup
wyatt-howe Sep 8, 2020
b2c866d
Correct misuse of `Math.random` and instead use `jiff.helpers.random`
wyatt-howe Nov 29, 2020
c761cc1
Lint code for readability and typos
wyatt-howe Nov 29, 2020
1adcad9
Disable logs for oblivious transfer—there're too many, and it works fine
wyatt-howe Nov 29, 2020
7c0c4ae
Typo in `jiff_debugging` extension
wyatt-howe Nov 29, 2020
7f7097b
Assert that party IDs be numbers
wyatt-howe Nov 29, 2020
538312b
Add arithmetic and composition GMW protocols
wyatt-howe Nov 29, 2020
42f0a6a
Preliminary demo demonstating arithmetic powered by GMW
wyatt-howe Nov 29, 2020
df50fbc
Finish GMW arithmetic demo (although no test.js yet)
wyatt-howe Nov 30, 2020
abb0302
Update jiff-client.js and remove a debugging line
wyatt-howe Nov 30, 2020
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
1 change: 1 addition & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ env:
- TEST_NAME='bigNumber-negativeNumber' TEST_SUITE=''
- TEST_NAME='restAPI' TEST_SUITE=''
- TEST_NAME='bits' TEST_SUITE=''
- TEST_NAME='GMW' TEST_SUITE=''
- TEST_NAME='fixedpoint' TEST_SUITE='share'
- TEST_NAME='fixedpoint' TEST_SUITE='arithmetic'
- TEST_NAME='fixedpoint' TEST_SUITE='constant arithmetic'
Expand Down
65 changes: 65 additions & 0 deletions demos/GMW-arithmetic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# GMW Demo with bitwise XOR/AND functionality

Description and guide for computing AND or XOR with secure MPC under GMW protocol.

## Protocol

The implementation of the following protocol may be found in jiff/demos/GMW-arithmetic/mpc.js lines 27 through 32.

Input: arbitrary number of parties P1,...Pn with bit inputs x1,...xn

Each party Pi does the following:
- secret shares their input xi to all other parties
- do XOR/AND between two shares, eg. shares[1],shares[2]
- reconstructs output in final opening step

## Notes on the code

The compute function in mpc.js executes once for every single party. In line 27 of *mpc.js*, the parties' shares are
created. It is important to note that the variable created in that line, *shares*, is not just the secret shares belonging
to a single parties' inputs but rather includes all shares that that party has received.

Note also that the parties have to iteratively use XOR/AND instead of doing a single one of their shares of x1,...,xn
I.e. if you have shares a, b, and c that you want to
xor, then you can't do
```
var output = a.gmw_xor(b,c);
```
but instead have to do
```
var c = a.gmw_xor(b);
var output = c.gmw_xor(d);
```
This is the same for the gmw_and function.

In this demo, we use gmw_and as an example, computing AND result for all parties' bit input.

## Legal inputs

This instantiation of XOR/AND only supports 0/1 as inputs.

## Running the demo
1. Running a server:
```shell
node demos/GMW-arithmetic/server.js
```
2. Either open browser based parties by going to *http://localhost:8080/demos/GMW-arithmetic/client.html* in the browser, or a node.js party by running
```shell
node demos/GMW-arithmetic/party.js <input> [<party count> [<computation_id> [<party id>]]]]'

3. Running tests: run the following. Note that you *do not* need to have the server running when running the tests; they run the server on their own.
```shell
npm run-script test-demo -- demos/GMW-arithmetic/test.js
```
## File structure
The demo consists of the following parts:
1. Server script: *server.js*
2. Web Based Party: Made from the following files:
* *client.html*: UI for the browser.
* *client.js*: Handlers for UI buttons and input validations.
3. Node.js-Based Party:
* *party.js*: Main entry point. Parses input from the command line and initializes the computation.
4. The MPC protocol: Implemented in *mpc.js*. This file is used in node.js versions of the demo.
5. test.js: mocha unit tests.
6. Documentation:
* This *README.md* file.
32 changes: 32 additions & 0 deletions demos/GMW-arithmetic/client.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<!-- Basic UI for running the demo in the browser -->

<html>
<head>
<title>GMW arithmetic computation under MPC</title>
<style>
.error {
color: #FF0000;
}
</style>
<script src="https://code.jquery.com/jquery-1.11.1.js"></script>
<script src="/lib/ext/jiff-client-debugging.js"></script>
<script src="/dist/jiff-client.js"></script>

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

<!-- Contains the MPC implementation -->
<script type="text/javascript" src="./mpc.js"></script>
</head>
<body>
<h1>Connect JIFF</h1>
<label for="computation_id">Computation ID</label><input id="computation_id" value="test"></input><br/><br/>
<label for="count">Party Count<label> <input id="count" pattern="[0-9]*" value="2"> &nbsp; <button id="connectButton" onclick="connect();">Connect</button>
<br/><br/>
<hr/>
<h1>Multiplication under MPC powered by the GMW protocol</h1>
<label for="bitlength">Maximum bit length of the inputs:</label> <input id="bitlength" pattern="[0-9]+" value="8"><br/><br/>
<label for="number">Input a positive whole number</label> <input id="number" pattern="[0-9]+" value="3"> &nbsp; <button onclick="submit();" disabled="disabled" id="button">compute</button><br/>
<div id="output"></div>
</body>
</html>
66 changes: 66 additions & 0 deletions demos/GMW-arithmetic/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Do not modify this file unless you have to.
* This file has UI handlers.
*/

// eslint-disable-next-line no-unused-vars
function connect() {
$('#connectButton').prop('disabled', true);
var computation_id = $('#computation_id').val();
var party_count = parseInt($('#count').val());

if (isNaN(party_count)) {
$('#output').append("<p class='error'>Party count must be a valid number!</p>");
$('#connectButton').prop('disabled', false);
} else {
var options = { party_count: party_count };
options.onError = function (_, error) {
$('#output').append("<p class='error'>"+error+'</p>');
};
options.onConnect = function () {
$('#button').attr('disabled', false); $('#output').append('<p>All parties Connected!</p>');
};

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);
}
}

// eslint-disable-next-line no-unused-vars
function submit() {
var input = parseInt($('#number').val());
var bit_length = parseInt($('#bitlength').val());

if (isNaN(input)) {
$('#output').append("<p class='error'>Input a valid number!</p>");
} else if (input < 0 || input !== Math.floor(input)) {
$('#output').append("<p class='error'>Input a positive whole number!</p>");
} else {
$('#button').attr('disabled', true);
$('#output').append('<p>Starting...</p>');
// eslint-disable-next-line no-undef
var promise = mpc.compute(input, bit_length);
promise.then(handleResult);
}
}

function handleResult(result) {
$('#output').append('<p>Result is: ' + result + '</p>');
$('#button').attr('disabled', false);
}
86 changes: 86 additions & 0 deletions demos/GMW-arithmetic/mpc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
(function (exports, node) {
var saved_instance;
// Unique prefix seed for op_ids
/**
* Connect to the server and initialize the jiff instance
*/
exports.connect = function (hostname, computation_id, options) {
var opt = Object.assign({}, options);
opt.warn = false;
opt.crypto_provider = true;
opt.sodium = false;

if (node) {
// eslint-disable-next-line no-undef
JIFFClient = require('../../lib/jiff-client');
// eslint-disable-next-line no-undef
jiff_debugging = require('../../lib/ext/jiff-client-debugging');
}

opt.autoConnect = false;
// eslint-disable-next-line no-undef
saved_instance = new JIFFClient(hostname, computation_id, opt);
// eslint-disable-next-line no-undef
saved_instance.apply_extension(jiff_debugging, opt);
saved_instance.connect();

return saved_instance;
};

exports.compute = function (input, bit_length, jiff_instance) {
var i, p_id;
if (jiff_instance == null) {
jiff_instance = saved_instance;
}

// Do initial conversion to bits locally.
var bits = jiff_instance.helpers.number_to_bits(input, bit_length); // maybe check to enforce correct lengths
console.log('input ', bits.join(''), input);

// Share all bits using GMW sharing
var shares = Array(1).concat(Array(jiff_instance.party_count).fill(Array()));
for (p_id = 1; p_id <= jiff_instance.party_count; p_id++) {
shares[p_id] = Array(bit_length);
}
for (i = 0; i < bit_length; i++) {
var bit = bits[i];
var share = jiff_instance.gmw_share(bit);
for (p_id = 1; p_id <= jiff_instance.party_count; p_id++) {
shares[p_id][i] = share[p_id];
}
}

// Multiply everyones' inputs together
var result = shares[1];
for (p_id = 2; p_id <= jiff_instance.party_count; p_id++) {
result = jiff_instance.protocols.gmw.bits.smult(result, shares[p_id]);
}

// Compose the GMW shares as a single polynomial share and return a promise to its reconstructed value.
return new Promise(function (resolve) {
Promise.all(result.map(function (bit_share) { // Wait for arithmetic to complete, then compose.
return bit_share.value; // a promise, if not ready
})).then(function () {
// Compose Shamir from GMW
jiff_instance.protocols.gmw.bits.compose(result).then(function (share) {
// Reveal the final output
share.open().then(function (value) {
var bits = jiff_instance.helpers.number_to_bits(value);
console.log('output ', bits.join(''), value);
resolve(value);
});
});
});

// Promise.all(
// result.map(function (bit_share) {
// return jiff_instance.gmw_open(bit_share);
// })
// ).then(function (bits) {
// var number = jiff_instance.helpers.bits_to_number(bits);
// console.log('output ', bits.join(''), number);
// resolve(number);
// });
});
}
}((typeof exports === 'undefined' ? this.mpc = {} : exports), typeof exports !== 'undefined'));
65 changes: 65 additions & 0 deletions demos/GMW-arithmetic/party.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
process.on('uncaughtException', function (err) {
console.log('Uncaught Exception!');
console.log(err);
throw err;
});
process.on('unhandledRejection', function (reason) {
console.log('Unhandled Rejection', reason);
});

/**
* 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
*/

console.log('Command line arguments: <input> <bit length> [<party count> [<computation_id> [<party id>]]]]');

var mpc = require('./mpc');


// Read Command line arguments
var input = parseInt(process.argv[2], 10);

// bit_length := the length of the input in bits a.k.a. at least log2(|input|). Must be the same for both parties.
var bit_length = process.argv[3];
if (bit_length != null) {
bit_length = parseInt(party_id, 10);
} else {
bit_length = 8;
}

var party_count = process.argv[4]; // n
if (party_count == null) {
party_count = 2;
} else {
party_count = parseInt(party_count);
}

var computation_id = process.argv[5];
if (computation_id == null) {
computation_id = 'test';
}

var party_id = process.argv[6];
if (party_id != null) {
party_id = parseInt(party_id, 10);
}

// JIFF options
var options = { party_count: party_count, party_id: party_id };

options.onConnect = function (jiff_instance) {
var promise = mpc.compute(input, bit_length, jiff_instance);
promise.then(function (value) {
console.log('result:', value);
jiff_instance.disconnect(true, true);
});

};

// Connect
mpc.connect('http://localhost:8080', computation_id, options);



22 changes: 22 additions & 0 deletions demos/GMW-arithmetic/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
var path = require('path');
var express = require('express');
var app = express();
var http = require('http').Server(app);

//Serve static files
//Configure App
app.use('/demos', express.static(path.join(__dirname, '..', '..', 'demos')));
app.use('/dist', express.static(path.join(__dirname, '..', '..', 'dist')));
app.use('/lib/ext', express.static(path.join(__dirname, '..', '..', 'lib', 'ext')));

var JIFFServer = require('../../lib/jiff-server.js');
new JIFFServer(http, { logs: true, sodium: false });

// Serve static files.
http.listen(8080, function () {
console.log('listening on *:8080');
});

console.log('Direct your browser to http://localhost:8080/demos/GMW-arithmetic/client.html.');
console.log('To run a node.js based party: node demos/GMW-arithmetic/party <input>');
console.log();
Loading