results from combining(a) and (a,b) are the same
Closed this issue · 2 comments
if you combine(a) and then combine(a,b) where a is a valid share and b an invalid share, the returned result appears to be the same. This is unexpected, for me at least ;)
Also, the result of a failed combine() does not seem to return strings.
(function() {
var secrets = require('secrets.js-grempe');
var seal = function(secret) {
return new Promise(function(resolve,reject) {
var hex = secrets.str2hex(secret);
var shares = secrets.share(hex,5,3,256);
resolve(shares);
});
};
var unseal_A = function(shares) {
var suppliedKeys = [];
return new Promise(function(resolve,reject) {
shares.forEach(function(share,index) {
suppliedKeys.push(share);
var result = secrets.hex2str(secrets.combine(suppliedKeys));
console.log("unseal_A",index,result);
});
resolve();
});
};
var unseal_B = function(shares) {
var suppliedKeys = [];
return new Promise(function(resolve,reject) {
shares.forEach(function(share,index) {
var dummy = [];
suppliedKeys.push(share);
/** so at this point, if we are under the threshold, creating a new share should result in garbage
*
* if, however, we are at the threshold, creating a new share should result in a vaild share, and
* valid shares pushed into a combine() would always return a secret
*
* invalid shares pushed into a combine() should return garbage
*
* so the theory was that if we are at a threshold, and add another valid key, the results of combine(suppliedKeys)
* and combine(suppliedKeys + newShare) would be the same, and therefore we would know that both the threshold
* has been reached and the key decrypted
*
* however, it seems that calling combine() with arrayA and ArrayA + another share also returns the same result
* just am invalid one :(
*/
dummy.push(secrets.newShare( index + 1, suppliedKeys ));
var resultA = secrets.hex2str(secrets.combine(suppliedKeys));
var resultB = secrets.hex2str(secrets.combine(suppliedKeys.concat(dummy)));
console.log("unseal_B",index,resultA,resultB,resultA === resultB);
});
resolve();
});
};
seal("foo123").then(function(keys) {
return unseal_A(keys).then(function() {
})
.then(function() {
return unseal_B(keys);
});
});
})();
would anyone care to comment if this project is abandoned or not ?
Sorry, for my terribly late response. Sadly, it's unlikely that you will find this helpful at this point I imagine. I'll give it a crack though.
Your example was well constructed. Its not clear to me though exactly what you thought would behave differently. The first two combine
operations for A
and B
do in fact combine the shares, but as expected the output has no relation to the original secret since they don't meet the threshold of 3
valid shares.
Referencing the README.md:
The output of secrets.combine() is a String representing the reconstructed secret. Note that this function will ALWAYS produce an output String. However, if the number of shares that are provided is not the threshold number of shares, the output will not be the original secret. In order to guarantee that the original secret is reconstructed, the correct threshold number of shares must be provided.
In your unseal B
example you get the same garbage values (expected) but you also create a new share which I imagine is valid for the insufficient shares you provided. Only when you provided three valid shares in unseal_B 2
did you not only unlock the original secret, but you created a new share that also worked. I think this is what is expected.
If this issue still has any meaning for you and you want to provide more info I'll be happy to re-open.
Cheers.