From 4a421d0384942cf4619bacea53d53ae01e7c0d22 Mon Sep 17 00:00:00 2001 From: Gagandeep Kang Date: Mon, 3 Aug 2020 13:21:00 -0400 Subject: [PATCH 1/9] add get/store preprocessing to hooks --- lib/client/arch/hooks.js | 11 ++++++++++- lib/client/preprocessing/daemon.js | 2 +- lib/client/preprocessing/handlers.js | 4 ++-- lib/client/protocols/bits/protocols.js | 4 ++-- lib/client/protocols/numbers/arithmetic.js | 6 +++--- lib/client/protocols/numbers/comparison.js | 2 +- lib/client/protocols/numbers/protocols.js | 4 ++-- 7 files changed, 21 insertions(+), 12 deletions(-) diff --git a/lib/client/arch/hooks.js b/lib/client/arch/hooks.js index 1ff616865..2deeb82e4 100644 --- a/lib/client/arch/hooks.js +++ b/lib/client/arch/hooks.js @@ -11,9 +11,9 @@ var crypto = require('../util/crypto.js'); var shamir_share = require('../protocols/shamir/share.js'); var shamir_open = require('../protocols/shamir/open.js'); + function Hooks(jiffClient) { this.jiffClient = jiffClient; - // avoid sharing aliases to the same array for (hook in Hooks.prototype) { if (Hooks.prototype.hasOwnProperty(hook) && typeof(Hooks.prototype[hook].length) === 'number' && Hooks.prototype[hook].slice) { @@ -45,6 +45,15 @@ function Hooks(jiffClient) { Hooks.prototype.computeShares = shamir_share.jiff_compute_shares; Hooks.prototype.reconstructShare = shamir_open.jiff_lagrange; +Hooks.prototype.getPreprocessing = function(jiffClient, op_id) { + return jiffClient.get_preprocessing(op_id); +} +Hooks.prototype.storePreprocessing = function(jiffClient, op_id, share) { + return jiffClient.store_preprocessing(op_id, share); +} + + + // Crypto hooks Hooks.prototype.encryptSign = function (jiffClient, message) { if (jiffClient.sodium_ !== false) { diff --git a/lib/client/preprocessing/daemon.js b/lib/client/preprocessing/daemon.js index 25c4599c9..53bfd53e7 100644 --- a/lib/client/preprocessing/daemon.js +++ b/lib/client/preprocessing/daemon.js @@ -85,7 +85,7 @@ module.exports = function (jiffClient) { currentBatchLoad--; if (task.receivers_list.indexOf(jiffClient.id) > -1) { - jiffClient.store_preprocessing(task.id, result.share); + jiffClient.hooks.storePreprocessing(jiffClient, task.id, result.share); } task.deferred.resolve(); jiffClient.preprocessingDaemon(); diff --git a/lib/client/preprocessing/handlers.js b/lib/client/preprocessing/handlers.js index 6c95861e0..315145060 100644 --- a/lib/client/preprocessing/handlers.js +++ b/lib/client/preprocessing/handlers.js @@ -139,7 +139,7 @@ module.exports = { if (previousPreprocessing == null || previousPreprocessing === 'RETRY' || (previousPreprocessing[0] != null && previousPreprocessing[0].value === 'RETRY')) { if (!params.defaultBounds && (params.lower_bound == null || params.upper_bound == null)) { - jiff.store_preprocessing(task.id, {ondemand: true}); + jiff.hooks.storePreprocessing(jiff, task.id, {ondemand: true}); return []; } @@ -224,7 +224,7 @@ module.exports = { ]; if (constantNotProvided) { - jiff.store_preprocessing(task_id, {ondemand: true}); + jiff.hooks.storePreprocessing(jiff, task_id, {ondemand: true}); return dependent_ops; } diff --git a/lib/client/protocols/bits/protocols.js b/lib/client/protocols/bits/protocols.js index ae558c92f..0e1bd6bad 100644 --- a/lib/client/protocols/bits/protocols.js +++ b/lib/client/protocols/bits/protocols.js @@ -30,7 +30,7 @@ module.exports = { } // try to get preprocessed samples - var result = jiff.get_preprocessing(op_id); + var result = jiff.hooks.getPreprocessing(jiff, op_id); if (result != null && result.ondemand !== true) { return result; } @@ -70,7 +70,7 @@ module.exports = { upper_bound: upper_bound }); jiff.executePreprocessing(function () { - jiff.utils.resolve_many_secrets(final_deferreds, jiff.get_preprocessing(op_id)); + jiff.utils.resolve_many_secrets(final_deferreds, jiff.hooks.getPreprocessing(jiff, op_id)); }); } diff --git a/lib/client/protocols/numbers/arithmetic.js b/lib/client/protocols/numbers/arithmetic.js index 2bfdaf2fa..cf354ceee 100644 --- a/lib/client/protocols/numbers/arithmetic.js +++ b/lib/client/protocols/numbers/arithmetic.js @@ -220,7 +220,7 @@ module.exports = function (SecretShare) { }; // Get shares of triplets. - var triplet = this.jiff.get_preprocessing(op_id + ':triplet'); + var triplet = this.jiff.hooks.getPreprocessing(this.jiff, op_id + ':triplet'); if (triplet == null) { var promise = this.jiff.from_crypto_provider('triplet', this.holders, Math.max(this.threshold, o.threshold), this.Zp, op_id + ':triplet'); promise.then(function (msg) { @@ -386,7 +386,7 @@ module.exports = function (SecretShare) { }; // Preprocessing cases - var quotient = this.jiff.get_preprocessing(op_id + ':quotient'); + var quotient = this.jiff.hooks.getPreprocessing(this.jiff, op_id + ':quotient'); if (quotient == null) { // case 1: no preprocessing with crypto provider! var promise = this.jiff.from_crypto_provider('quotient', this.holders, this.threshold, this.Zp, op_id + ':quotient', {constant: cst}); promise.then(function (msg) { @@ -395,7 +395,7 @@ module.exports = function (SecretShare) { } else if (quotient.ondemand === true) { // case 2: constant was not available at preprocessing time, must do it now! this.jiff.preprocessing('quotient', 1, null, this.threshold, this.holders, this.holders, this.Zp, [op_id + ':quotient'], {constant: cst, namespace: 'base'}); this.jiff.executePreprocessing(function () { - var quotient = self.jiff.get_preprocessing(op_id + ':quotient'); + var quotient = self.jiff.hooks.getPreprocessing(self.jiff, op_id + ':quotient'); ready_quotient(quotient.r, quotient.q); }); } else { // case 3: preprocessing is completed! diff --git a/lib/client/protocols/numbers/comparison.js b/lib/client/protocols/numbers/comparison.js index 9fd688134..220df71d1 100644 --- a/lib/client/protocols/numbers/comparison.js +++ b/lib/client/protocols/numbers/comparison.js @@ -411,7 +411,7 @@ module.exports = function (SecretShare) { }; // generate the bits of a random number less than our prime - var bits = this.jiff.get_preprocessing(op_id + ':sampling'); + var bits = this.jiff.hooks.getPreprocessing(this.jiff, op_id + ':sampling'); if (bits == null) { var promise = this.jiff.from_crypto_provider('numbers', this.holders, this.threshold, this.Zp, op_id + ':sampling', { bitLength: bitLength, diff --git a/lib/client/protocols/numbers/protocols.js b/lib/client/protocols/numbers/protocols.js index 9ae133e9a..86dbd0f60 100644 --- a/lib/client/protocols/numbers/protocols.js +++ b/lib/client/protocols/numbers/protocols.js @@ -27,7 +27,7 @@ module.exports = function (SecretShare) { }; // get shares of zero - var zero = this.jiff.get_preprocessing(op_id); + var zero = this.jiff.hooks.getPreprocessing(this.jiff, op_id); if (zero == null) { var promise = this.jiff.from_crypto_provider('numbers', this.holders, this.threshold, this.Zp, op_id, { number: 0, @@ -90,7 +90,7 @@ module.exports = function (SecretShare) { }; // generate the bits of a random number less than our prime - var bits = this.jiff.get_preprocessing(op_id + ':sampling'); + var bits = this.jiff.hooks.getPreprocessing(this.jiff, op_id + ':sampling'); if (bits == null) { var promise = this.jiff.from_crypto_provider('numbers', this.holders, this.threshold, this.Zp, op_id + ':sampling', { bitLength: bitLength, From ed430ff98a6d7250102c780036fab7c8f6b99ce6 Mon Sep 17 00:00:00 2001 From: Gagandeep Kang Date: Mon, 3 Aug 2020 14:37:59 -0400 Subject: [PATCH 2/9] add mpc average demo --- demos/average/README.md | 37 ++++++++++++ demos/average/client.html | 30 +++++++++ demos/average/client.js | 67 ++++++++++++++++++++ demos/average/mpc.js | 41 +++++++++++++ demos/average/party.js | 43 +++++++++++++ demos/average/server.js | 18 ++++++ demos/average/test.js | 124 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 360 insertions(+) create mode 100644 demos/average/README.md create mode 100644 demos/average/client.html create mode 100644 demos/average/client.js create mode 100644 demos/average/mpc.js create mode 100644 demos/average/party.js create mode 100644 demos/average/server.js create mode 100644 demos/average/test.js diff --git a/demos/average/README.md b/demos/average/README.md new file mode 100644 index 000000000..9bc3f5007 --- /dev/null +++ b/demos/average/README.md @@ -0,0 +1,37 @@ +# Demos Template + +Internal template for use when creating templates. + +## File structure +Demos should consist of the following parts: +1. Server script: the defaul server script should be enough unless (1) additional extensions are applied. (2) server side computation is needed. +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*. You should code your protocol in the compute function inside mpc.js, this file is used in both the browser +and node.js versions of the demo. +5. test.js: mocha unit tests. + +## File to modify +1. client.html: change the title and different labels, as well as the UI if needed. +2. mpc.js: to encode your protocol and use any needed extensions. +3. test.js: generic test code should work for most demos, you will need to add code to generate appropriate inputs/test cases, and to compute the expected results (not in MPC) for these inputs. +4. server.js: Modify the last two lines in the template file (logs) to show the right command to run the parties. + +## Running Demos +1. Running a server: +```shell +node index.js demos//server.js +``` + +2. Either open browser based parties by going to *http://localhost:8080/demos//client.html* in the browser, or a node.js party by running +```shell +node party.js +``` + +3. Running tests: make sure a server is running and then use: +```shell +npm run-script test-demo -- demos//test.js +``` diff --git a/demos/average/client.html b/demos/average/client.html new file mode 100644 index 000000000..2c4b5f7dd --- /dev/null +++ b/demos/average/client.html @@ -0,0 +1,30 @@ + + + + + Average Numbers under MPC + + + + + + + + + + + +

Connect JIFF

+

+