-
Notifications
You must be signed in to change notification settings - Fork 53
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
review changes for parties receiving multiple shares #169
Open
sashni
wants to merge
1
commit into
master
Choose a base branch
from
receiveMultipleShares
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+79
−49
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -186,7 +186,7 @@ | |
* if the party that calls this function is not a receiver then the map | ||
* will be empty. | ||
*/ | ||
function jiff_share(jiff, secret, threshold, receivers_list, senders_list, Zp, share_id) { | ||
function jiff_share(jiff, secret, threshold, receivers_list, senders_list, Zp, share_id, receivers_ratios) { | ||
var i, p_id; | ||
|
||
// defaults | ||
|
@@ -214,6 +214,12 @@ | |
if (threshold > receivers_list.length) { | ||
threshold = receivers_list.length; | ||
} | ||
if (receivers_ratios == null) { | ||
receivers_ratios = {}; | ||
for (var i = 1; i <= jiff.party_count; i++){ | ||
receivers_ratios[i] = 2; | ||
} | ||
} | ||
|
||
// if party is uninvolved in the share, do nothing | ||
if (receivers_list.indexOf(jiff.id) === -1 && senders_list.indexOf(jiff.id) === -1) { | ||
|
@@ -233,7 +239,7 @@ | |
secret = jiff.execute_array_hooks('beforeShare', [jiff, secret, threshold, receivers_list, senders_list, Zp], 1); | ||
|
||
// compute shares | ||
var shares = jiff.hooks.computeShares(jiff, secret, receivers_list, threshold, Zp); | ||
var shares = jiff.hooks.computeShares(jiff, secret, receivers_list, threshold, Zp, receivers_ratios); | ||
|
||
// Call hook | ||
shares = jiff.execute_array_hooks('afterComputeShare', [jiff, shares, threshold, receivers_list, senders_list, Zp], 1); | ||
|
@@ -246,10 +252,13 @@ | |
} | ||
|
||
// send encrypted and signed shares_id[p_id] to party p_id | ||
var msg = { party_id: p_id, share: shares[p_id], op_id: share_id }; | ||
var p_ratio = (p_id in receivers_ratios) ? receivers_ratios[p_id] : 1; | ||
var msg = {party_id: p_id, share: shares[p_id].slice(), op_id: share_id}; | ||
msg = jiff.execute_array_hooks('beforeOperation', [jiff, 'share', msg], 2); | ||
|
||
msg['share'] = jiff.hooks.encryptSign(jiff, msg['share'].toString(10), jiff.keymap[msg['party_id']], jiff.secret_key); | ||
for (var j = 0; j < p_ratio; j++) { | ||
msg['share'][j] = jiff.hooks.encryptSign(jiff, msg['share'][j].toString(10), jiff.keymap[msg['party_id']], jiff.secret_key); | ||
} | ||
jiff.socket.safe_emit('share', JSON.stringify(msg)); | ||
} | ||
} | ||
|
@@ -285,11 +294,10 @@ | |
}); | ||
})(promise, p_id); | ||
|
||
// receive share_i[id] from party p_id | ||
//receive share_i[id] from party p_id | ||
result[p_id] = jiff.secret_share(jiff, false, promise, undefined, receivers_list, threshold, Zp, share_id + ':' + p_id); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
|
@@ -308,7 +316,7 @@ | |
* point from the polynomial. | ||
* | ||
*/ | ||
function jiff_compute_shares(jiff, secret, parties_list, threshold, Zp) { | ||
function jiff_compute_shares(jiff, secret, parties_list, threshold, Zp, parties_ratios) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does |
||
var shares = {}; // Keeps the shares | ||
var i; | ||
|
||
|
@@ -330,16 +338,19 @@ | |
// Compute each players share such that share[i] = f(i) | ||
for (i = 0; i < parties_list.length; i++) { | ||
var p_id = parties_list[i]; | ||
shares[p_id] = polynomial[0]; | ||
var power = jiff.helpers.get_party_number(p_id); | ||
|
||
for (var j = 1; j < polynomial.length; j++) { | ||
var tmp = jiff.helpers.mod((polynomial[j] * power), Zp); | ||
shares[p_id] = jiff.helpers.mod((shares[p_id] + tmp), Zp); | ||
power = jiff.helpers.mod(power * jiff.helpers.get_party_number(p_id), Zp); | ||
var p_ratio = p_id in parties_ratios ? parties_ratios[p_id] : 1; | ||
shares[p_id] = []; | ||
for (var share_num = 0; share_num < p_ratio; share_num++) { | ||
shares[p_id][share_num] = polynomial[0]; | ||
var power = jiff.helpers.get_party_number(p_id, share_num); | ||
|
||
for (var j = 1; j < polynomial.length; j++) { | ||
var tmp = jiff.helpers.mod((polynomial[j] * power), Zp); | ||
shares[p_id][share_num] = jiff.helpers.mod((shares[p_id][share_num] + tmp), Zp); | ||
power = jiff.helpers.mod(power * jiff.helpers.get_party_number(p_id, share_num), Zp); | ||
} | ||
} | ||
} | ||
|
||
return shares; | ||
} | ||
|
||
|
@@ -352,7 +363,10 @@ | |
*/ | ||
function receive_share(jiff, json_msg) { | ||
// Decrypt share | ||
json_msg['share'] = jiff.hooks.decryptSign(jiff, json_msg['share'], jiff.secret_key, jiff.keymap[json_msg['party_id']]); | ||
var num_shares = json_msg['share'].length; | ||
for (var i = 0; i < num_shares; i++) { | ||
json_msg['share'][i] = jiff.hooks.decryptSign(jiff, json_msg['share'][i], jiff.secret_key, jiff.keymap[json_msg['party_id']]); | ||
} | ||
json_msg = jiff.execute_array_hooks('afterOperation', [jiff, 'share', json_msg], 2); | ||
|
||
var sender_id = json_msg['party_id']; | ||
|
@@ -452,6 +466,7 @@ | |
// Party is a receiver | ||
if (parties.indexOf(jiff.id) > -1) { | ||
var shares = []; // this will store received shares | ||
var numberofshares = 0; | ||
var final_deferred = new Deferred(); // will be resolved when the final value is reconstructed | ||
var final_promise = final_deferred.promise; | ||
for (i = 0; i < share.holders.length; i++) { | ||
|
@@ -473,9 +488,10 @@ | |
promise.then(function (received_share) { | ||
jiff.deferreds[op_ids[jiff.id]][p_id] = null; | ||
shares.push(received_share); | ||
numberofshares = numberofshares + received_share.value.length; | ||
|
||
// Too few shares, nothing to do. | ||
if (shares.length < share.threshold) { | ||
if (numberofshares < share.threshold) { | ||
return; | ||
} | ||
|
||
|
@@ -484,7 +500,6 @@ | |
if (final_deferred != null) { | ||
var recons_secret = jiff.hooks.reconstructShare(jiff, shares); | ||
recons_secret = jiff.execute_array_hooks('afterReconstructShare', [jiff, recons_secret], 1); | ||
|
||
final_deferred.resolve(recons_secret); | ||
final_deferred = null; | ||
} | ||
|
@@ -518,15 +533,17 @@ | |
for (var index = 0; index < parties.length; index++) { | ||
var i = parties[index]; // Party id | ||
if (i === jiff.id) { | ||
receive_open(jiff, { party_id: i, share: share.value, op_id: op_ids[i], Zp: share.Zp }); | ||
receive_open(jiff, {party_id: i, share: share.value, op_id: op_ids[i], Zp: share.Zp}); | ||
continue; | ||
} | ||
|
||
// encrypt, sign and send | ||
var msg = {party_id: i, share: share.value, op_id: op_ids[i], Zp: share.Zp}; | ||
var msg = {party_id: i, share: share.value.slice(), op_id: op_ids[i], Zp: share.Zp}; | ||
msg = jiff.execute_array_hooks('beforeOperation', [jiff, 'open', msg], 2); | ||
|
||
msg['share'] = jiff.hooks.encryptSign(jiff, msg['share'].toString(), jiff.keymap[msg['party_id']], jiff.secret_key); | ||
for (var j = 0; j < msg['share'].length; j++) { | ||
msg['share'][j] = jiff.hooks.encryptSign(jiff, msg['share'][j].toString(), jiff.keymap[msg['party_id']], jiff.secret_key); | ||
} | ||
jiff.socket.safe_emit('open', JSON.stringify(msg)); | ||
} | ||
} | ||
|
@@ -540,7 +557,9 @@ | |
function receive_open(jiff, json_msg) { | ||
// Decrypt share | ||
if (json_msg['party_id'] !== jiff.id) { | ||
json_msg['share'] = jiff.hooks.decryptSign(jiff, json_msg['share'], jiff.secret_key, jiff.keymap[json_msg['party_id']]); | ||
for (var i = 0; i < json_msg['share'].length; i++) { | ||
json_msg['share'][i] = jiff.hooks.decryptSign(jiff, json_msg['share'][i], jiff.secret_key, jiff.keymap[json_msg['party_id']]); | ||
} | ||
json_msg = jiff.execute_array_hooks('afterOperation', [jiff, 'open', json_msg], 2); | ||
} | ||
|
||
|
@@ -576,29 +595,34 @@ | |
function jiff_lagrange(jiff, shares) { | ||
var lagrange_coeff = []; // will contain shares.length many elements. | ||
|
||
// Compute the Langrange coefficients at 0. | ||
// Compute the Lagrange coefficients at 0. | ||
for (var i = 0; i < shares.length; i++) { | ||
var pi = jiff.helpers.get_party_number(shares[i].sender_id); | ||
lagrange_coeff[pi] = 1; | ||
|
||
for (var j = 0; j < shares.length; j++) { | ||
var pj = jiff.helpers.get_party_number(shares[j].sender_id); | ||
if (pj !== pi) { | ||
var inv = jiff.helpers.extended_gcd(pi - pj, shares[i].Zp)[0]; | ||
lagrange_coeff[pi] = jiff.helpers.mod(lagrange_coeff[pi] * (0 - pj), shares[i].Zp) * inv; | ||
lagrange_coeff[pi] = jiff.helpers.mod(lagrange_coeff[pi], shares[i].Zp); | ||
for (var share_num = 0; share_num < shares[i].value.length; share_num++) { | ||
var pi = jiff.helpers.get_party_number(shares[i].sender_id, share_num); | ||
lagrange_coeff[pi] = 1; | ||
|
||
for (var j = 0; j < shares.length; j++) { | ||
for (var n = 0; n < shares[j].value.length; n++) { | ||
var pj = jiff.helpers.get_party_number(shares[j].sender_id, n); | ||
if (pj !== pi) { | ||
var inv = jiff.helpers.extended_gcd(pi - pj, shares[i].Zp)[0]; | ||
lagrange_coeff[pi] = jiff.helpers.mod(lagrange_coeff[pi] * (0 - pj), shares[i].Zp) * inv; | ||
lagrange_coeff[pi] = jiff.helpers.mod(lagrange_coeff[pi], shares[i].Zp); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Reconstruct the secret via Lagrange interpolation | ||
var recons_secret = 0; | ||
for (var p = 0; p < shares.length; p++) { | ||
var party = jiff.helpers.get_party_number(shares[p].sender_id); | ||
var tmp = jiff.helpers.mod((shares[p].value * lagrange_coeff[party]), shares[p].Zp); | ||
recons_secret = jiff.helpers.mod((recons_secret + tmp), shares[p].Zp); | ||
for (share_num = 0; share_num < shares[p].value.length; share_num++) { | ||
var party = jiff.helpers.get_party_number(shares[p].sender_id, share_num); | ||
var tmp = jiff.helpers.mod((shares[p].value[share_num] * lagrange_coeff[party]), shares[p].Zp); | ||
recons_secret = jiff.helpers.mod((recons_secret + tmp), shares[p].Zp); | ||
} | ||
} | ||
|
||
return recons_secret; | ||
} | ||
|
||
|
@@ -1298,7 +1322,7 @@ | |
* @param {jiff-instance} jiff - the jiff instance. | ||
* @param {boolean} ready - whether the value of the share is ready or deferred. | ||
* @param {promise} promise - a promise to the value of the share. | ||
* @param {number} value - the value of the share (null if not ready). | ||
* @param {Array} value - the value of the share (null if not ready). | ||
* @param {Array} holders - the parties that hold all the corresponding shares (must be sorted). | ||
* @param {number} threshold - the min number of parties needed to reconstruct the secret. | ||
* @param {number} Zp - the mod under which this share was created. | ||
|
@@ -1377,7 +1401,7 @@ | |
*/ | ||
self.promise = promise; | ||
/** | ||
* @member {number} value | ||
* @member {Array} value | ||
* @memberof SecretShare | ||
* @instance | ||
*/ | ||
|
@@ -1532,7 +1556,8 @@ | |
* @instance | ||
*/ | ||
self.refresh = function (op_id) { | ||
return self.isadd(self.jiff.server_generate_and_share({number: 0}, self.holders, self.threshold, self.Zp, op_id)[0]); | ||
return self | ||
//return self.isadd(self.jiff.server_generate_and_share({number: 0}, self.holders, self.threshold, self.Zp, op_id)[0]); | ||
}; | ||
|
||
/** | ||
|
@@ -3374,7 +3399,9 @@ | |
// parse content of share/open messages to be integers (instead of strings due to encryption/decryption) | ||
jiff.hooks.afterOperation.unshift(function (jiff, label, msg) { | ||
if (label === 'share' || label === 'open') { | ||
msg['share'] = parseInt(msg['share'], 10); | ||
for (var i = 0; i < msg['share'].length; i++) { | ||
msg['share'][i] = parseInt(msg['share'][i], 10); | ||
} | ||
} | ||
return msg; | ||
}); | ||
|
@@ -3851,14 +3878,17 @@ | |
* @param {number/string} party_id - the party id from which to compute the number. | ||
* @return {number} the party number (> 0). | ||
*/ | ||
jiff.helpers.get_party_number = function (party_id) { | ||
jiff.helpers.get_party_number = function (party_id, share_num) { | ||
if (share_num == null){ | ||
share_num = 0; | ||
} | ||
if (typeof(party_id) === 'number') { | ||
return party_id; | ||
return party_id + (share_num * (jiff.party_count+1)); | ||
} | ||
if (party_id.startsWith('s')) { | ||
return -1 * parseInt(party_id.substring(1), 10); | ||
return parseInt(party_id.substring(1), 10) * (jiff.party_count+1); // n+1 reserved for server | ||
} | ||
return parseInt(party_id, 10); | ||
return parseInt(party_id, 10) + (share_num * (jiff.party_count+1)); | ||
}; | ||
|
||
/** | ||
|
@@ -3903,7 +3933,7 @@ | |
* and the value is the share object that wraps | ||
* the value sent from that party (the internal value maybe deferred). | ||
*/ | ||
jiff.share = function (secret, threshold, receivers_list, senders_list, Zp, share_id) { | ||
jiff.share = function (secret, threshold, receivers_list, senders_list, Zp, share_id, receivers_ratios) { | ||
// type check to confirm the secret to be shared is a number | ||
// for fixed-point extension it should allow non-ints | ||
if (secret != null && (typeof(secret) !== 'number' || Math.floor(secret) !== secret || secret < 0)) { | ||
|
@@ -3912,14 +3942,14 @@ | |
if (secret != null && (secret >= (Zp == null ? jiff.Zp : Zp))) { | ||
throw new Error('secret must fit inside Zp'); | ||
} | ||
return jiff.internal_share(secret, threshold, receivers_list, senders_list, Zp, share_id); | ||
return jiff.internal_share(secret, threshold, receivers_list, senders_list, Zp, share_id, receivers_ratios); | ||
}; | ||
|
||
/** | ||
* Same as jiff-instance.share, but used by internal JIFF primitives/protocols (bgw). | ||
*/ | ||
jiff.internal_share = function (secret, threshold, receivers_list, senders_list, Zp, share_id) { | ||
return jiff_share(jiff, secret, threshold, receivers_list, senders_list, Zp, share_id); | ||
jiff.internal_share = function (secret, threshold, receivers_list, senders_list, Zp, share_id, receivers_ratios) { | ||
return jiff_share(jiff, secret, threshold, receivers_list, senders_list, Zp, share_id, receivers_ratios); | ||
}; | ||
|
||
/** | ||
|
@@ -4728,7 +4758,7 @@ | |
|
||
// Setup receiving matching shares | ||
jiff.socket.on('share', function (msg, callback) { | ||
callback(true); // send ack to server | ||
callback(true); // send back to server | ||
|
||
// parse message | ||
var json_msg = JSON.parse(msg); | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Please what is the rational for setting to 2.