UNPKG

smartledger-sdk

Version:

A comprehensive blockchain and cryptographic operations SDK for JavaScript

107 lines (99 loc) 3.77 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = exports.SecretSharer = void 0; var _shamirsSecretSharing = _interopRequireDefault(require("shamirs-secret-sharing")); var _buffer = require("buffer"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } class SecretSharer { constructor() { this.sss = _shamirsSecretSharing.default; } /** * Split a secret into multiple shares using Shamir's Secret Sharing * @param {string} secret - The secret to split * @param {number} shares - Number of shares to create * @param {number} threshold - Minimum number of shares needed to reconstruct * @returns {Array<Buffer>} Array of secret shares */ splitSecret(secret, shares, threshold) { if (!secret || typeof secret !== "string") { throw new Error("Secret must be a non-empty string"); } if (!Number.isInteger(shares) || shares < 2) { throw new Error("Number of shares must be an integer >= 2"); } if (!Number.isInteger(threshold) || threshold < 2 || threshold > shares) { throw new Error("Threshold must be an integer >= 2 and <= number of shares"); } const secretBuffer = _buffer.Buffer.from(secret, "utf8"); const result = this.sss.split(secretBuffer, { shares, threshold }); return Array.from(result); } /** * Combine shares to reconstruct the original secret * @param {Array<Buffer>} shares - Array of shares to combine * @returns {string} The reconstructed secret */ combineShares(shares) { if (!Array.isArray(shares) || shares.length < 2) { throw new Error("Must provide at least 2 shares"); } try { const recoveredBuffer = this.sss.combine(shares); return recoveredBuffer.toString("utf8"); } catch (error) { throw new Error("Failed to reconstruct secret: " + error.message); } } /** * Convert a share to a hex string for storage or transmission * @param {Buffer} share - The share to convert * @returns {string} Hex string representation of the share */ shareToHex(share) { if (!_buffer.Buffer.isBuffer(share)) { // Convert Uint8Array to Buffer if needed if (share instanceof Uint8Array) { share = _buffer.Buffer.from(share); } else { throw new Error("Share must be a Buffer or Uint8Array"); } } return share.toString("hex"); } /** * Convert a hex string back to a share Buffer * @param {string} hexShare - Hex string representation of a share * @returns {Buffer} The share as a Buffer */ hexToShare(hexShare) { if (typeof hexShare !== "string" || !/^[0-9a-fA-F]+$/.test(hexShare)) { throw new Error("Invalid hex string"); } return _buffer.Buffer.from(hexShare, "hex"); } } // Example usage exports.SecretSharer = SecretSharer; if (import.meta.url === `file://${process.cwd()}/SecretSharer.js`) { const sharer = new SecretSharer(); const secret = "my secret"; console.log("\nExample of Shamir's Secret Sharing:"); console.log("-----------------------------------"); console.log("Original secret:", secret); // Split the secret into 3 shares (need 2 to reconstruct) const shares = sharer.splitSecret(secret, 3, 2); console.log("\nGenerated", shares.length, "shares (need 2 to reconstruct):"); const hexShares = shares.map(share => sharer.shareToHex(share)); hexShares.forEach((share, i) => console.log(`Share ${i + 1}:`, share)); // Reconstruct using just 2 of the 3 shares const sharesToUse = shares.slice(0, 2); const reconstructed = sharer.combineShares(sharesToUse); console.log("\nReconstructed secret using 2 shares:", reconstructed); } var _default = exports.default = SecretSharer;