PHP WebShell
Текущая директория: /opt/BitGoJS/modules/sdk-lib-mpc/dist/src/shamir
Просмотр файла: shamir.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Shamir = void 0;
const crypto_1 = __importDefault(require("crypto"));
const util_1 = require("../util");
class Shamir {
constructor(curve) {
this.curve = curve;
}
/**
* Perform Shamir sharing on the secret `secret` to the degree `threshold - 1` split `numShares`
* ways. The split secret requires `threshold` shares to be reconstructed.
*
* @param secret secret to split
* @param threshold share threshold required to reconstruct secret
* @param numShares total number of shares to split secret into
* @param indices optional indices which can be used while generating the shares
* @param salt optional salt which could be used while generating the shares
* @returns Dictionary containing `shares`, a dictionary where each key is an int
* in the range 1<=x<=numShares representing that share's free term, and `v`, an
* array of proofs to be shared with all participants.
*/
split(secret, threshold, numShares, indices, salt = BigInt(0)) {
let bigIndices;
if (indices) {
bigIndices = indices.map((i) => {
if (i < 1) {
throw new Error('Invalid value supplied for indices');
}
return BigInt(i);
});
}
else {
// make range(1, n + 1)
bigIndices = Array(numShares)
.fill(null)
.map((_, i) => BigInt(i + 1));
}
if (threshold < 2) {
throw new Error('Threshold cannot be less than two');
}
if (threshold > numShares) {
throw new Error('Threshold cannot be greater than the total number of shares');
}
const coefs = [];
const v = [];
for (let ind = 0; ind < threshold - 1; ind++) {
const coeff = (0, util_1.clamp)((0, util_1.bigIntFromBufferLE)(crypto_1.default.createHmac('sha256', ind.toString(10)).update((0, util_1.bigIntToBufferLE)(secret, 32)).digest()));
coefs.push(coeff);
v.unshift(this.curve.basePointMult(coeff));
}
coefs.push(secret);
const shares = {};
for (let ind = 0; ind < bigIndices.length; ind++) {
const x = bigIndices[ind];
let partial = coefs[0];
for (let other = 1; other < coefs.length; other++) {
partial = this.curve.scalarAdd(coefs[other], this.curve.scalarMult(partial, x));
}
shares[parseInt(x.toString(), 10)] = partial;
}
return { shares, v };
}
/**
* Verify a VSS share.
*
* @param u Secret share received from other party.
* @param v Verification values received from other party.
* @param index Verifier's index.
* @returns True on success; otherwise throws Error.
*/
verify(u, v, index) {
if (v.length < 2) {
throw new Error('Threshold cannot be less than two');
}
if (index < 1) {
throw new Error('Invalid value supplied for index');
}
const i = BigInt(index);
let x = v[0];
let t = BigInt(1);
for (const vsj of v.slice(1)) {
t = this.curve.scalarMult(t, i);
const vjt = this.curve.pointMultiply(vsj, t);
x = this.curve.pointAdd(x, vjt);
}
const sigmaG = this.curve.basePointMult(u);
if (x !== sigmaG) {
throw new Error('Could not verify share');
}
return true;
}
/**
* Reconstitute a secret from a dictionary of shares. The number of shares must
* be equal to `t` to reconstitute the original secret.
*
* @param shares dictionary of shares. each key is the free term of the share
* @returns secret
*/
combine(shares) {
try {
let s = BigInt(0);
for (const i in shares) {
const yi = shares[i];
const xi = BigInt(i);
let num = BigInt(1);
let denum = BigInt(1);
for (const j in shares) {
const xj = BigInt(j);
if (xi !== xj) {
num = this.curve.scalarMult(num, xj);
}
}
for (const j in shares) {
const xj = BigInt(j);
if (xi !== xj) {
denum = this.curve.scalarMult(denum, this.curve.scalarSub(xj, xi));
}
}
const inverted = this.curve.scalarInvert(denum);
const innerMultiplied = this.curve.scalarMult(num, inverted);
const multiplied = this.curve.scalarMult(innerMultiplied, yi);
s = this.curve.scalarAdd(multiplied, s);
}
return s;
}
catch (error) {
throw new Error('Failed to combine Shamir shares , ' + error);
}
}
}
exports.Shamir = Shamir;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhbWlyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL3NoYW1pci9zaGFtaXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsb0RBQTRCO0FBRzVCLGtDQUFzRTtBQUV0RSxNQUFhLE1BQU07SUFHakIsWUFBWSxLQUFnQjtRQUMxQixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUNyQixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7OztPQVlHO0lBQ0gsS0FBSyxDQUFDLE1BQWMsRUFBRSxTQUFpQixFQUFFLFNBQWlCLEVBQUUsT0FBdUIsRUFBRSxJQUFJLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztRQUNuRyxJQUFJLFVBQXlCLENBQUM7UUFDOUIsSUFBSSxPQUFPLEVBQUUsQ0FBQztZQUNaLFVBQVUsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQzdCLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO29CQUNWLE1BQU0sSUFBSSxLQUFLLENBQUMsb0NBQW9DLENBQUMsQ0FBQztnQkFDeEQsQ0FBQztnQkFDRCxPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQixDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7YUFBTSxDQUFDO1lBQ04sdUJBQXVCO1lBQ3ZCLFVBQVUsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO2lCQUMxQixJQUFJLENBQUMsSUFBSSxDQUFDO2lCQUNWLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsQyxDQUFDO1FBQ0QsSUFBSSxTQUFTLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbEIsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBbUMsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7UUFFRCxJQUFJLFNBQVMsR0FBRyxTQUFTLEVB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QUNkLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7b0JBQ3JFLENBQUM7Z0JBQ0gsQ0FBQztnQkFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDaEQsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUM3RCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQzlELENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQyxDQUFDLENBQUM7WUFDMUMsQ0FBQztZQUNELE9BQU8sQ0FBQyxDQUFDO1FBQ1gsQ0FBQztRQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7WUFDZixNQUFNLElBQUksS0FBSyxDQUFDLG9DQUFvQyxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQ2hFLENBQUM7SUFDSCxDQUFDO0NBQ0Y7QUF0SUQsd0JBc0lDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IGNyeXB0byBmcm9tICdjcnlwdG8nO1xuaW1wb3J0IHsgQmFzZUN1cnZlIH0gZnJvbSAnLi4vY3VydmVzJztcbmltcG9ydCB7IFNwbGl0U2VjcmV0IH0gZnJvbSAnLi90eXBlcyc7XG5pbXBvcnQgeyBiaWdJbnRGcm9tQnVmZmVyTEUsIGJpZ0ludFRvQnVmZmVyTEUsIGNsYW1wIH0gZnJvbSAnLi4vdXRpbCc7XG5cbmV4cG9ydCBjbGFzcyBTaGFtaXIge1xuICBjdXJ2ZTogQmFzZUN1cnZlO1xuXG4gIGNvbnN0cnVjdG9yKGN1cnZlOiBCYXNlQ3VydmUpIHtcbiAgICB0aGlzLmN1cnZlID0gY3VydmU7XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSBTaGFtaXIgc2hhcmluZyBvbiB0aGUgc2VjcmV0IGBzZWNyZXRgIHRvIHRoZSBkZWdyZWUgYHRocmVzaG9sZCAtIDFgIHNwbGl0IGBudW1TaGFyZXNgXG4gICAqIHdheXMuIFRoZSBzcGxpdCBzZWNyZXQgcmVxdWlyZXMgYHRocmVzaG9sZGAgc2hhcmVzIHRvIGJlIHJlY29uc3RydWN0ZWQuXG4gICAqXG4gICAqIEBwYXJhbSBzZWNyZXQgc2VjcmV0IHRvIHNwbGl0XG4gICAqIEBwYXJhbSB0aHJlc2hvbGQgc2hhcmUgdGhyZXNob2xkIHJlcXVpcmVkIHRvIHJlY29uc3RydWN0IHNlY3JldFxuICAgKiBAcGFyYW0gbnVtU2hhcmVzIHRvdGFsIG51bWJlciBvZiBzaGFyZXMgdG8gc3BsaXQgc2VjcmV0IGludG9cbiAgICogQHBhcmFtIGluZGljZXMgb3B0aW9uYWwgaW5kaWNlcyB3aGljaCBjYW4gYmUgdXNlZCB3aGlsZSBnZW5lcmF0aW5nIHRoZSBzaGFyZXNcbiAgICogQHBhcmFtIHNhbHQgb3B0aW9uYWwgc2FsdCB3aGljaCBjb3VsZCBiZSB1c2VkIHdoaWxlIGdlbmVyYXRpbmcgdGhlIHNoYXJlc1xuICAgKiBAcmV0dXJucyBEaWN0aW9uYXJ5IGNvbnRhaW5pbmcgYHNoYXJlc2AsIGEgZGljdGlvbmFyeSB3aGVyZSBlYWNoIGtleSBpcyBhbiBpbnRcbiAgICogaW4gdGhlIHJhbmdlIDE8PXg8PW51bVNoYXJlcyByZXByZXNlbnRpbmcgdGhhdCBzaGFyZSdzIGZyZWUgdGVybSwgYW5kIGB2YCwgYW5cbiAgICogYXJyYXkgb2YgcHJvb2ZzIHRvIGJlIHNoYXJlZCB3aXRoIGFsbCBwYXJ0aWNpcGFudHMuXG4gICAqL1xuICBzcGxpdChzZWNyZXQ6IGJpZ2ludCwgdGhyZXNob2xkOiBudW1iZXIsIG51bVNoYXJlczogbnVtYmVyLCBpbmRpY2VzPzogQXJyYXk8bnVtYmVyPiwgc2FsdCA9IEJpZ0ludCgwKSk6IFNwbGl0U2VjcmV0IHtcbiAgICBsZXQgYmlnSW5kaWNlczogQXJyYXk8YmlnaW50PjtcbiAgICBpZiAoaW5kaWNlcykge1xuICAgICAgYmlnSW5kaWNlcyA9IGluZGljZXMubWFwKChpKSA9PiB7XG4gICAgICAgIGlmIChpIDwgMSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCB2YWx1ZSBzdXBwbGllZCBmb3IgaW5kaWNlcycpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBCaWdJbnQoaSk7XG4gICAgICB9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbWFrZSByYW5nZSgxLCBuICsgMSlcbiAgICAgIGJpZ0luZGljZXMgPSBBcnJheShudW1TaGFyZXMpXG4gICAgICAgIC5maWxsKG51bGwpXG4gICAgICAgIC5tYXAoKF8sIGkpID0+IEJpZ0ludChpICsgMSkpO1xuICAgIH1cbiAgICBpZiAodGhyZXNob2xkIDwgMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaHJlc2hvbGQgY2Fubm90IGJlIGxlc3MgdGhhbiB0d28nKTtcbiAgICB9XG5cbiAgICBpZiAodGhyZXNob2xkID4gbnVtU2hhcmVzKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1RocmVzaG9sZCBjYW5ub3QgYmUgZ3JlYXRlciB0aGFuIHRoZSB0b3RhbCBudW1iZXIgb2Ygc2hhcmVzJyk7XG4gICAgfVxuXG4gICAgY29uc3QgY29lZnM6IGJpZ2ludFtdID0gW107XG4gICAgY29uc3QgdjogQXJyYXk8YmlnaW50PiA9IFtdO1xuICAgIGZvciAobGV0IGluZCA9IDA7IGluZCA8IHRocmVzaG9sZCAtIDE7IGluZCsrKSB7XG4gICAgICBjb25zdCBjb2VmZiA9IGNsYW1wKFxuICAgICAgICBiaWdJbnRGcm9tQnVmZmVyTEUoY3J5cHRvLmNyZWF0ZUhtYWMoJ3NoYTI1NicsIGluZC50b1N0cmluZygxMCkpLnVwZGF0ZShiaWdJbnRUb0J1ZmZlckxFKHNlY3JldCwgMzIpKS5kaWdlc3QoKSlcbiAgICAgICk7XG4gICAgICBjb2Vmcy5wdXNoKGNvZWZmKTtcbiAgICAgIHYudW5zaGlmdCh0aGlzLmN1cnZlLmJhc2VQb2ludE11bHQoY29lZmYpKTtcbiAgICB9XG4gICAgY29lZnMucHVzaChzZWNyZXQpO1xuXG4gICAgY29uc3Qgc2hhcmVzOiBSZWNvcmQ8bnVtYmVyLCBiaWdpbnQ+ID0ge307XG4gICAgZm9yIChsZXQgaW5kID0gMDsgaW5kIDwgYmlnSW5kaWNlcy5sZW5ndGg7IGluZCsrKSB7XG4gICAgICBjb25zdCB4ID0gYmlnSW5kaWNlc1tpbmRdO1xuICAgICAgbGV0IHBhcnRpYWwgPSBjb2Vmc1swXTtcbiAgICAgIGZvciAobGV0IG90aGVyID0gMTsgb3RoZXIgPCBjb2Vmcy5sZW5ndGg7IG90aGVyKyspIHtcbiAgICAgICAgcGFydGlhbCA9IHRoaXMuY3VydmUuc2NhbGFyQWRkKGNvZWZzW290aGVyXSwgdGhpcy5jdXJ2ZS5zY2FsYXJNdWx0KHBhcnRpYWwsIHgpKTtcbiAgICAgIH1cbiAgICAgIHNoYXJlc1twYXJzZUludCh4LnRvU3RyaW5nKCksIDEwKV0gPSBwYXJ0aWFsO1xuICAgIH1cbiAgICByZXR1cm4geyBzaGFyZXMsIHYgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBWZXJpZnkgYSBWU1Mgc2hhcmUuXG4gICAqXG4gICAqIEBwYXJhbSB1IFNlY3JldCBzaGFyZSByZWNlaXZlZCBmcm9tIG90aGVyIHBhcnR5LlxuICAgKiBAcGFyYW0gdiBWZXJpZmljYXRpb24gdmFsdWVzIHJlY2VpdmVkIGZyb20gb3RoZXIgcGFydHkuXG4gICAqIEBwYXJhbSBpbmRleCBWZXJpZmllcidzIGluZGV4LlxuICAgKiBAcmV0dXJucyBUcnVlIG9uIHN1Y2Nlc3M7IG90aGVyd2lzZSB0aHJvd3MgRXJyb3IuXG4gICAqL1xuICB2ZXJpZnkodTogYmlnaW50LCB2OiBBcnJheTxiaWdpbnQ+LCBpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKHYubGVuZ3RoIDwgMikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaHJlc2hvbGQgY2Fubm90IGJlIGxlc3MgdGhhbiB0d28nKTtcbiAgICB9XG4gICAgaWYgKGluZGV4IDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHZhbHVlIHN1cHBsaWVkIGZvciBpbmRleCcpO1xuICAgIH1cbiAgICBjb25zdCBpID0gQmlnSW50KGluZGV4KTtcbiAgICBsZXQgeCA9IHZbMF07XG4gICAgbGV0IHQgPSBCaWdJbnQoMSk7XG4gICAgZm9yIChjb25zdCB2c2ogb2Ygdi5zbGljZSgxKSkge1xuICAgICAgdCA9IHRoaXMuY3VydmUuc2NhbGFyTXVsdCh0LCBpKTtcbiAgICAgIGNvbnN0IHZqdCA9IHRoaXMuY3VydmUucG9pbnRNdWx0aXBseSh2c2osIHQpO1xuICAgICAgeCA9IHRoaXMuY3VydmUucG9pbnRBZGQoeCwgdmp0KTtcbiAgICB9XG4gICAgY29uc3Qgc2lnbWFHID0gdGhpcy5jdXJ2ZS5iYXNlUG9pbnRNdWx0KHUpO1xuICAgIGlmICh4ICE9PSBzaWdtYUcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignQ291bGQgbm90IHZlcmlmeSBzaGFyZScpO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvbnN0aXR1dGUgYSBzZWNyZXQgZnJvbSBhIGRpY3Rpb25hcnkgb2Ygc2hhcmVzLiBUaGUgbnVtYmVyIG9mIHNoYXJlcyBtdXN0XG4gICAqIGJlIGVxdWFsIHRvIGB0YCB0byByZWNvbnN0aXR1dGUgdGhlIG9yaWdpbmFsIHNlY3JldC5cbiAgICpcbiAgICogQHBhcmFtIHNoYXJlcyBkaWN0aW9uYXJ5IG9mIHNoYXJlcy4gZWFjaCBrZXkgaXMgdGhlIGZyZWUgdGVybSBvZiB0aGUgc2hhcmVcbiAgICogQHJldHVybnMgc2VjcmV0XG4gICAqL1xuICBjb21iaW5lKHNoYXJlczogUmVjb3JkPG51bWJlciwgYmlnaW50Pik6IGJpZ2ludCB7XG4gICAgdHJ5IHtcbiAgICAgIGxldCBzID0gQmlnSW50KDApO1xuICAgICAgZm9yIChjb25zdCBpIGluIHNoYXJlcykge1xuICAgICAgICBjb25zdCB5aSA9IHNoYXJlc1tpXTtcbiAgICAgICAgY29uc3QgeGkgPSBCaWdJbnQoaSk7XG4gICAgICAgIGxldCBudW0gPSBCaWdJbnQoMSk7XG4gICAgICAgIGxldCBkZW51bSA9IEJpZ0ludCgxKTtcblxuICAgICAgICBmb3IgKGNvbnN0IGogaW4gc2hhcmVzKSB7XG4gICAgICAgICAgY29uc3QgeGogPSBCaWdJbnQoaik7XG4gICAgICAgICAgaWYgKHhpICE9PSB4aikge1xuICAgICAgICAgICAgbnVtID0gdGhpcy5jdXJ2ZS5zY2FsYXJNdWx0KG51bSwgeGopO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IGogaW4gc2hhcmVzKSB7XG4gICAgICAgICAgY29uc3QgeGogPSBCaWdJbnQoaik7XG4gICAgICAgICAgaWYgKHhpICE9PSB4aikge1xuICAgICAgICAgICAgZGVudW0gPSB0aGlzLmN1cnZlLnNjYWxhck11bHQoZGVudW0sIHRoaXMuY3VydmUuc2NhbGFyU3ViKHhqLCB4aSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbnZlcnRlZCA9IHRoaXMuY3VydmUuc2NhbGFySW52ZXJ0KGRlbnVtKTtcbiAgICAgICAgY29uc3QgaW5uZXJNdWx0aXBsaWVkID0gdGhpcy5jdXJ2ZS5zY2FsYXJNdWx0KG51bSwgaW52ZXJ0ZWQpO1xuICAgICAgICBjb25zdCBtdWx0aXBsaWVkID0gdGhpcy5jdXJ2ZS5zY2FsYXJNdWx0KGlubmVyTXVsdGlwbGllZCwgeWkpO1xuICAgICAgICBzID0gdGhpcy5jdXJ2ZS5zY2FsYXJBZGQobXVsdGlwbGllZCwgcyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gcztcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGYWlsZWQgdG8gY29tYmluZSBTaGFtaXIgc2hhcmVzICwgJyArIGVycm9yKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==Выполнить команду
Для локальной разработки. Не используйте в интернете!