@bcts/shamir 1.0.0-alpha.8 → 1.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +3 -2
- package/dist/index.cjs +103 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -78
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +34 -78
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +125 -89
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +88 -44
- package/dist/index.mjs.map +1 -1
- package/package.json +16 -17
- package/src/error.ts +30 -0
- package/src/hazmat.ts +40 -28
- package/src/index.ts +6 -14
- package/src/interpolate.ts +6 -0
- package/src/shamir.ts +6 -0
package/dist/index.iife.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.iife.js","names":["lxi: Uint32Array[]","y: Uint8Array[]","result: Uint8Array[]","y: Uint8Array[]"],"sources":["../src/error.ts","../src/hazmat.ts","../src/interpolate.ts","../src/shamir.ts","../src/index.ts"],"sourcesContent":["// Ported from bc-shamir-rust/src/error.rs\n\n/**\n * Error types for Shamir secret sharing operations.\n */\nexport enum ShamirErrorType {\n SecretTooLong = \"SecretTooLong\",\n TooManyShares = \"TooManyShares\",\n InterpolationFailure = \"InterpolationFailure\",\n ChecksumFailure = \"ChecksumFailure\",\n SecretTooShort = \"SecretTooShort\",\n SecretNotEvenLen = \"SecretNotEvenLen\",\n InvalidThreshold = \"InvalidThreshold\",\n SharesUnequalLength = \"SharesUnequalLength\",\n}\n\n/**\n * Error class for Shamir secret sharing operations.\n */\nexport class ShamirError extends Error {\n readonly type: ShamirErrorType;\n\n constructor(type: ShamirErrorType, message?: string) {\n super(message ?? ShamirError.defaultMessage(type));\n this.type = type;\n this.name = \"ShamirError\";\n }\n\n private static defaultMessage(type: ShamirErrorType): string {\n switch (type) {\n case ShamirErrorType.SecretTooLong:\n return \"secret is too long\";\n case ShamirErrorType.TooManyShares:\n return \"too many shares\";\n case ShamirErrorType.InterpolationFailure:\n return \"interpolation failed\";\n case ShamirErrorType.ChecksumFailure:\n return \"checksum failure\";\n case ShamirErrorType.SecretTooShort:\n return \"secret is too short\";\n case ShamirErrorType.SecretNotEvenLen:\n return \"secret is not of even length\";\n case ShamirErrorType.InvalidThreshold:\n return \"invalid threshold\";\n case ShamirErrorType.SharesUnequalLength:\n return \"shares have unequal length\";\n }\n }\n}\n\nexport type ShamirResult<T> = T;\n","// Ported from bc-shamir-rust/src/hazmat.rs\n// GF(2^8) bitsliced polynomial operations for Shamir secret sharing\n\nimport { memzero } from \"@bcts/crypto\";\n\n/**\n * Convert an array of bytes into a bitsliced representation.\n * Takes the first 32 bytes from x and produces 8 u32 values.\n *\n * @param r - Output array of 8 u32 values (bitsliced representation)\n * @param x - Input array of at least 32 bytes\n */\nexport function bitslice(r: Uint32Array, x: Uint8Array): void {\n if (x.length < 32) {\n throw new Error(\"bitslice: input must be at least 32 bytes\");\n }\n if (r.length !== 8) {\n throw new Error(\"bitslice: output must have 8 elements\");\n }\n\n memzero(r);\n\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n const cur = x[arrIdx];\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n // r[bitIdx] |= ((cur & (1 << bitIdx)) >> bitIdx) << arrIdx\n r[bitIdx] |= ((cur & (1 << bitIdx)) >>> bitIdx) << arrIdx;\n }\n }\n}\n\n/**\n * Convert a bitsliced representation back to bytes.\n *\n * @param r - Output array of at least 32 bytes\n * @param x - Input array of 8 u32 values (bitsliced representation)\n */\nexport function unbitslice(r: Uint8Array, x: Uint32Array): void {\n if (r.length < 32) {\n throw new Error(\"unbitslice: output must be at least 32 bytes\");\n }\n if (x.length !== 8) {\n throw new Error(\"unbitslice: input must have 8 elements\");\n }\n\n memzero(r.subarray(0, 32));\n\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n const cur = x[bitIdx];\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n // r[arrIdx] |= ((cur & (1 << arrIdx)) >> arrIdx) << bitIdx\n r[arrIdx] |= ((cur & (1 << arrIdx)) >>> arrIdx) << bitIdx;\n }\n }\n}\n\n/**\n * Set all 32 positions in a bitsliced array to the same byte value.\n *\n * @param r - Output array of 8 u32 values\n * @param x - Byte value to set in all positions\n */\nexport function bitsliceSetall(r: Uint32Array, x: number): void {\n if (r.length !== 8) {\n throw new Error(\"bitsliceSetall: output must have 8 elements\");\n }\n\n for (let idx = 0; idx < 8; idx++) {\n // JavaScript needs special handling for the arithmetic right shift\n // This mirrors: *r = (((((x as u32) & (1u32.wrapping_shl(idx as u32)))\n // .wrapping_shl(31 - idx as u32)) as i32)\n // .wrapping_shr(31)) as u32;\n const bit = (x >>> idx) & 1;\n r[idx] = bit === 1 ? 0xffffffff : 0;\n }\n}\n\n/**\n * Add (XOR) r with x and store the result in r.\n * In GF(2^8), addition is XOR.\n *\n * @param r - First operand and result\n * @param x - Second operand\n */\nexport function gf256Add(r: Uint32Array, x: Uint32Array): void {\n if (r.length !== 8 || x.length !== 8) {\n throw new Error(\"gf256Add: arrays must have 8 elements\");\n }\n\n for (let i = 0; i < 8; i++) {\n r[i] ^= x[i];\n }\n}\n\n/**\n * Safely multiply two bitsliced polynomials in GF(2^8) reduced by\n * x^8 + x^4 + x^3 + x + 1. r and a may overlap, but overlapping of r\n * and b will produce an incorrect result! If you need to square a polynomial\n * use gf256Square instead.\n *\n * @param r - Result array (8 u32 values)\n * @param a - First operand (may overlap with r)\n * @param b - Second operand (must NOT overlap with r)\n */\nexport function gf256Mul(r: Uint32Array, a: Uint32Array, b: Uint32Array): void {\n if (r.length !== 8 || a.length !== 8 || b.length !== 8) {\n throw new Error(\"gf256Mul: arrays must have 8 elements\");\n }\n\n // Russian Peasant multiplication on two bitsliced polynomials\n const a2 = new Uint32Array(a);\n\n r[0] = a2[0] & b[0];\n r[1] = a2[1] & b[0];\n r[2] = a2[2] & b[0];\n r[3] = a2[3] & b[0];\n r[4] = a2[4] & b[0];\n r[5] = a2[5] & b[0];\n r[6] = a2[6] & b[0];\n r[7] = a2[7] & b[0];\n a2[0] ^= a2[7]; // reduce\n a2[2] ^= a2[7];\n a2[3] ^= a2[7];\n\n r[0] ^= a2[7] & b[1]; // add\n r[1] ^= a2[0] & b[1];\n r[2] ^= a2[1] & b[1];\n r[3] ^= a2[2] & b[1];\n r[4] ^= a2[3] & b[1];\n r[5] ^= a2[4] & b[1];\n r[6] ^= a2[5] & b[1];\n r[7] ^= a2[6] & b[1];\n a2[7] ^= a2[6]; // reduce\n a2[1] ^= a2[6];\n a2[2] ^= a2[6];\n\n r[0] ^= a2[6] & b[2]; // add\n r[1] ^= a2[7] & b[2];\n r[2] ^= a2[0] & b[2];\n r[3] ^= a2[1] & b[2];\n r[4] ^= a2[2] & b[2];\n r[5] ^= a2[3] & b[2];\n r[6] ^= a2[4] & b[2];\n r[7] ^= a2[5] & b[2];\n a2[6] ^= a2[5]; // reduce\n a2[0] ^= a2[5];\n a2[1] ^= a2[5];\n\n r[0] ^= a2[5] & b[3]; // add\n r[1] ^= a2[6] & b[3];\n r[2] ^= a2[7] & b[3];\n r[3] ^= a2[0] & b[3];\n r[4] ^= a2[1] & b[3];\n r[5] ^= a2[2] & b[3];\n r[6] ^= a2[3] & b[3];\n r[7] ^= a2[4] & b[3];\n a2[5] ^= a2[4]; // reduce\n a2[7] ^= a2[4];\n a2[0] ^= a2[4];\n\n r[0] ^= a2[4] & b[4]; // add\n r[1] ^= a2[5] & b[4];\n r[2] ^= a2[6] & b[4];\n r[3] ^= a2[7] & b[4];\n r[4] ^= a2[0] & b[4];\n r[5] ^= a2[1] & b[4];\n r[6] ^= a2[2] & b[4];\n r[7] ^= a2[3] & b[4];\n a2[4] ^= a2[3]; // reduce\n a2[6] ^= a2[3];\n a2[7] ^= a2[3];\n\n r[0] ^= a2[3] & b[5]; // add\n r[1] ^= a2[4] & b[5];\n r[2] ^= a2[5] & b[5];\n r[3] ^= a2[6] & b[5];\n r[4] ^= a2[7] & b[5];\n r[5] ^= a2[0] & b[5];\n r[6] ^= a2[1] & b[5];\n r[7] ^= a2[2] & b[5];\n a2[3] ^= a2[2]; // reduce\n a2[5] ^= a2[2];\n a2[6] ^= a2[2];\n\n r[0] ^= a2[2] & b[6]; // add\n r[1] ^= a2[3] & b[6];\n r[2] ^= a2[4] & b[6];\n r[3] ^= a2[5] & b[6];\n r[4] ^= a2[6] & b[6];\n r[5] ^= a2[7] & b[6];\n r[6] ^= a2[0] & b[6];\n r[7] ^= a2[1] & b[6];\n a2[2] ^= a2[1]; // reduce\n a2[4] ^= a2[1];\n a2[5] ^= a2[1];\n\n r[0] ^= a2[1] & b[7]; // add\n r[1] ^= a2[2] & b[7];\n r[2] ^= a2[3] & b[7];\n r[3] ^= a2[4] & b[7];\n r[4] ^= a2[5] & b[7];\n r[5] ^= a2[6] & b[7];\n r[6] ^= a2[7] & b[7];\n r[7] ^= a2[0] & b[7];\n}\n\n/**\n * Square x in GF(2^8) and write the result to r.\n * r and x may overlap.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to square\n */\nexport function gf256Square(r: Uint32Array, x: Uint32Array): void {\n if (r.length !== 8 || x.length !== 8) {\n throw new Error(\"gf256Square: arrays must have 8 elements\");\n }\n\n // Use the Freshman's Dream rule to square the polynomial\n // Assignments are done from 7 downto 0, because this allows\n // in-place operation (e.g. gf256Square(r, r))\n const r14 = x[7];\n const r12 = x[6];\n let r10 = x[5];\n let r8 = x[4];\n r[6] = x[3];\n r[4] = x[2];\n r[2] = x[1];\n r[0] = x[0];\n\n // Reduce with x^8 + x^4 + x^3 + x + 1 until order is less than 8\n r[7] = r14; // r[7] was 0\n r[6] ^= r14;\n r10 ^= r14;\n // Skip, because r13 is always 0\n r[4] ^= r12;\n r[5] = r12; // r[5] was 0\n r[7] ^= r12;\n r8 ^= r12;\n // Skip, because r11 is always 0\n r[2] ^= r10;\n r[3] = r10; // r[3] was 0\n r[5] ^= r10;\n r[6] ^= r10;\n r[1] = r14; // r[1] was 0\n r[2] ^= r14; // Substitute r9 by r14 because they will always be equal\n r[4] ^= r14;\n r[5] ^= r14;\n r[0] ^= r8;\n r[1] ^= r8;\n r[3] ^= r8;\n r[4] ^= r8;\n}\n\n/**\n * Invert x in GF(2^8) and write the result to r.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to invert (will be modified)\n */\nexport function gf256Inv(r: Uint32Array, x: Uint32Array): void {\n if (r.length !== 8 || x.length !== 8) {\n throw new Error(\"gf256Inv: arrays must have 8 elements\");\n }\n\n const y = new Uint32Array(8);\n const z = new Uint32Array(8);\n\n gf256Square(y, x); // y = x^2\n const y2 = new Uint32Array(y);\n gf256Square(y, y2); // y = x^4\n gf256Square(r, y); // r = x^8\n gf256Mul(z, r, x); // z = x^9\n const r2a = new Uint32Array(r);\n gf256Square(r, r2a); // r = x^16\n const r2b = new Uint32Array(r);\n gf256Mul(r, r2b, z); // r = x^25\n const r2c = new Uint32Array(r);\n gf256Square(r, r2c); // r = x^50\n gf256Square(z, r); // z = x^100\n const z2 = new Uint32Array(z);\n gf256Square(z, z2); // z = x^200\n const r2d = new Uint32Array(r);\n gf256Mul(r, r2d, z); // r = x^250\n const r2e = new Uint32Array(r);\n gf256Mul(r, r2e, y); // r = x^254\n}\n","// Ported from bc-shamir-rust/src/interpolate.rs\n\nimport { memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport { MAX_SECRET_LEN } from \"./index.js\";\nimport { bitslice, bitsliceSetall, gf256Add, gf256Inv, gf256Mul, unbitslice } from \"./hazmat.js\";\n\n/**\n * Calculate the lagrange basis coefficients for the lagrange polynomial\n * defined by the x coordinates xc at the value x.\n *\n * After the function runs, the values array should hold data satisfying:\n * --- (x-xc[j])\n * values[i] = | | -------------\n * j != i (xc[i]-xc[j])\n *\n * @param values - Output array for the lagrange basis values\n * @param n - Number of points (length of the xc array, 0 < n <= 32)\n * @param xc - Array of x components to use as interpolating points\n * @param x - x coordinate to evaluate lagrange polynomials at\n */\nfunction hazmatLagrangeBasis(values: Uint8Array, n: number, xc: Uint8Array, x: number): void {\n // call the contents of xc [ x0 x1 x2 ... xn-1 ]\n const xx = new Uint8Array(32 + 16);\n const xSlice = new Uint32Array(8);\n const lxi: Uint32Array[] = [];\n for (let i = 0; i < n; i++) {\n lxi.push(new Uint32Array(8));\n }\n const numerator = new Uint32Array(8);\n const denominator = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n xx.set(xc.subarray(0, n), 0);\n\n // xx now contains bitsliced [ x0 x1 x2 ... xn-1 0 0 0 ... ]\n for (let i = 0; i < n; i++) {\n // lxi = bitsliced [ xi xi+1 xi+2 ... xi-1 0 0 0 ]\n bitslice(lxi[i], xx.subarray(i));\n xx[i + n] = xx[i];\n }\n\n bitsliceSetall(xSlice, x);\n bitsliceSetall(numerator, 1);\n bitsliceSetall(denominator, 1);\n\n for (let i = 1; i < n; i++) {\n temp.set(xSlice);\n gf256Add(temp, lxi[i]);\n // temp = [ x-xi+i x-xi+2 x-xi+3 ... x-xi x x x]\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n temp.set(lxi[0]);\n gf256Add(temp, lxi[i]);\n // temp = [x0-xi+1 x1-xi+1 x2-xi+2 ... xn-x0 0 0 0]\n const denominator2 = new Uint32Array(denominator);\n gf256Mul(denominator, denominator2, temp);\n }\n\n // At this stage the numerator contains\n // [ num0 num1 num2 ... numn 0 0 0]\n //\n // where numi = prod(j, j!=i, x-xj )\n //\n // and the denominator contains\n // [ d0 d1 d2 ... dn 0 0 0]\n //\n // where di = prod(j, j!=i, xi-xj)\n\n gf256Inv(temp, denominator);\n\n // gf256_inv uses exponentiation to calculate inverse, so the zeros end up\n // remaining zeros.\n\n // tmp = [ 1/d0 1/d1 1/d2 ... 1/dn 0 0 0]\n\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n // numerator now contains [ l_n_0(x) l_n_1(x) ... l_n_n-1(x) 0 0 0]\n // use the xx array to unpack it\n\n unbitslice(xx, numerator);\n\n // copy results to output array\n values.set(xx.subarray(0, n), 0);\n}\n\n/**\n * Safely interpolate the polynomial going through\n * the points (x0 [y0_0 y0_1 y0_2 ... y0_31]) , (x1 [y1_0 ...]), ...\n *\n * where\n * xi points to [x0 x1 ... xn-1 ]\n * y contains an array of pointers to 32-bit arrays of y values\n * y contains [y0 y1 y2 ... yn-1]\n * and each of the yi arrays contain [yi_0 yi_i ... yi_31].\n *\n * @param n - Number of points to interpolate\n * @param xi - x coordinates for points (array of length n)\n * @param yl - Length of y coordinate arrays\n * @param yij - Array of n arrays of length yl\n * @param x - Coordinate to interpolate at\n * @returns The interpolated result of length yl\n */\nexport function interpolate(\n n: number,\n xi: Uint8Array,\n yl: number,\n yij: Uint8Array[],\n x: number,\n): Uint8Array {\n // The hazmat gf256 implementation needs the y-coordinate data\n // to be in 32-byte blocks\n const y: Uint8Array[] = [];\n for (let i = 0; i < n; i++) {\n y.push(new Uint8Array(MAX_SECRET_LEN));\n }\n const values = new Uint8Array(MAX_SECRET_LEN);\n\n for (let i = 0; i < n; i++) {\n y[i].set(yij[i].subarray(0, yl), 0);\n }\n\n const lagrange = new Uint8Array(n);\n const ySlice = new Uint32Array(8);\n const resultSlice = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n hazmatLagrangeBasis(lagrange, n, xi, x);\n\n bitsliceSetall(resultSlice, 0);\n\n for (let i = 0; i < n; i++) {\n bitslice(ySlice, y[i]);\n bitsliceSetall(temp, lagrange[i]);\n const temp2 = new Uint32Array(temp);\n gf256Mul(temp, temp2, ySlice);\n gf256Add(resultSlice, temp);\n }\n\n unbitslice(values, resultSlice);\n\n // the calling code is only expecting yl bytes back\n const result = new Uint8Array(yl);\n result.set(values.subarray(0, yl), 0);\n\n // clean up stack\n memzero(lagrange);\n memzero(ySlice);\n memzero(resultSlice);\n memzero(temp);\n memzeroVecVecU8(y);\n memzero(values);\n\n return result;\n}\n","// Ported from bc-shamir-rust/src/shamir.rs\n\nimport { hmacSha256, memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\n\nimport { ShamirError, ShamirErrorType } from \"./error.js\";\nimport { MAX_SECRET_LEN, MAX_SHARE_COUNT, MIN_SECRET_LEN } from \"./index.js\";\nimport { interpolate } from \"./interpolate.js\";\n\nconst SECRET_INDEX = 255;\nconst DIGEST_INDEX = 254;\n\nfunction createDigest(randomData: Uint8Array, sharedSecret: Uint8Array): Uint8Array {\n return hmacSha256(randomData, sharedSecret);\n}\n\nfunction validateParameters(threshold: number, shareCount: number, secretLength: number): void {\n if (shareCount > MAX_SHARE_COUNT) {\n throw new ShamirError(ShamirErrorType.TooManyShares);\n } else if (threshold < 1 || threshold > shareCount) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n } else if (secretLength > MAX_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooLong);\n } else if (secretLength < MIN_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooShort);\n } else if ((secretLength & 1) !== 0) {\n throw new ShamirError(ShamirErrorType.SecretNotEvenLen);\n }\n}\n\n/**\n * Splits a secret into shares using the Shamir secret sharing algorithm.\n *\n * @param threshold - The minimum number of shares required to reconstruct the\n * secret. Must be greater than or equal to 1 and less than or equal to\n * shareCount.\n * @param shareCount - The total number of shares to generate. Must be at least\n * threshold and less than or equal to MAX_SHARE_COUNT.\n * @param secret - A Uint8Array containing the secret to be split. Must be at\n * least MIN_SECRET_LEN bytes long and at most MAX_SECRET_LEN bytes long.\n * The length must be an even number.\n * @param randomGenerator - An implementation of the RandomNumberGenerator\n * interface, used to generate random data.\n * @returns An array of Uint8Array representing the shares of the secret.\n * @throws ShamirError if parameters are invalid\n *\n * @example\n * ```typescript\n * import { splitSecret } from \"@bcts/shamir\";\n * import { SecureRandomNumberGenerator } from \"@bcts/rand\";\n *\n * const threshold = 2;\n * const shareCount = 3;\n * const secret = new TextEncoder().encode(\"my secret belongs to me.\");\n * const rng = new SecureRandomNumberGenerator();\n *\n * const shares = splitSecret(threshold, shareCount, secret, rng);\n * console.log(shares.length); // 3\n * ```\n */\nexport function splitSecret(\n threshold: number,\n shareCount: number,\n secret: Uint8Array,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[] {\n validateParameters(threshold, shareCount, secret.length);\n\n if (threshold === 1) {\n // just return shareCount copies of the secret\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret));\n }\n return result;\n } else {\n const x = new Uint8Array(shareCount);\n const y: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n y.push(new Uint8Array(secret.length));\n }\n let n = 0;\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret.length));\n }\n\n for (let index = 0; index < threshold - 2; index++) {\n randomGenerator.fillRandomData(result[index]);\n x[n] = index;\n y[n].set(result[index]);\n n++;\n }\n\n // generate secret_length - 4 bytes worth of random data\n const digest = new Uint8Array(secret.length);\n randomGenerator.fillRandomData(digest.subarray(4));\n // put 4 bytes of digest at the top of the digest array\n const d = createDigest(digest.subarray(4), secret);\n digest.set(d.subarray(0, 4), 0);\n x[n] = DIGEST_INDEX;\n y[n].set(digest);\n n++;\n\n x[n] = SECRET_INDEX;\n y[n].set(secret);\n n++;\n\n for (let index = threshold - 2; index < shareCount; index++) {\n const v = interpolate(n, x, secret.length, y, index);\n result[index].set(v);\n }\n\n // clean up stack\n memzero(digest);\n memzero(x);\n memzeroVecVecU8(y);\n\n return result;\n }\n}\n\n/**\n * Recovers the secret from the given shares using the Shamir secret sharing\n * algorithm.\n *\n * @param indexes - An array of indexes of the shares to be used for recovering\n * the secret. These are the indexes of the shares returned by splitSecret.\n * @param shares - An array of shares of the secret matching the indexes in\n * indexes. These are the shares returned by splitSecret.\n * @returns A Uint8Array representing the recovered secret.\n * @throws ShamirError if parameters are invalid or checksum verification fails\n *\n * @example\n * ```typescript\n * import { recoverSecret } from \"@bcts/shamir\";\n *\n * const indexes = [0, 2];\n * const shares = [\n * new Uint8Array([47, 165, 102, 232, ...]),\n * new Uint8Array([221, 174, 116, 201, ...]),\n * ];\n *\n * const secret = recoverSecret(indexes, shares);\n * console.log(new TextDecoder().decode(secret)); // \"my secret belongs to me.\"\n * ```\n */\nexport function recoverSecret(indexes: number[], shares: Uint8Array[]): Uint8Array {\n const threshold = shares.length;\n if (threshold === 0 || indexes.length !== threshold) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n }\n\n const shareLength = shares[0].length;\n validateParameters(threshold, threshold, shareLength);\n\n const allSameLength = shares.every((share) => share.length === shareLength);\n if (!allSameLength) {\n throw new ShamirError(ShamirErrorType.SharesUnequalLength);\n }\n\n if (threshold === 1) {\n return new Uint8Array(shares[0]);\n } else {\n const indexesU8 = new Uint8Array(indexes);\n\n const digest = interpolate(threshold, indexesU8, shareLength, shares, DIGEST_INDEX);\n const secret = interpolate(threshold, indexesU8, shareLength, shares, SECRET_INDEX);\n const verify = createDigest(digest.subarray(4), secret);\n\n let valid = true;\n for (let i = 0; i < 4; i++) {\n valid = valid && digest[i] === verify[i];\n }\n\n memzero(digest);\n memzero(verify);\n\n if (!valid) {\n throw new ShamirError(ShamirErrorType.ChecksumFailure);\n }\n\n return secret;\n }\n}\n","// Blockchain Commons Shamir Secret Sharing\n// Ported from bc-shamir-rust\n//\n// This is a pure TypeScript implementation of Shamir's Secret Sharing (SSS),\n// a cryptographic technique in which a secret is divided into parts, called\n// shares, in such a way that a threshold of several shares are needed to\n// reconstruct the secret. The shares are distributed in a way that makes it\n// impossible for an attacker to know anything about the secret without having\n// a threshold of shares. If the number of shares is less than the threshold,\n// then no information about the secret is revealed.\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = 16;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = 32;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = 16;\n\n// Error types\nexport { ShamirError, ShamirErrorType, type ShamirResult } from \"./error.js\";\n\n// Main functions\nexport { splitSecret, recoverSecret } from \"./shamir.js\";\n\n// Low-level operations (hazmat)\nexport {\n bitslice,\n unbitslice,\n bitsliceSetall,\n gf256Add,\n gf256Mul,\n gf256Square,\n gf256Inv,\n} from \"./hazmat.js\";\n\n// Interpolation\nexport { interpolate } from \"./interpolate.js\";\n"],"mappings":"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,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AACl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"}
|
|
1
|
+
{"version":3,"file":"index.iife.js","names":[],"sources":["../src/error.ts","../src/hazmat.ts","../src/interpolate.ts","../src/shamir.ts","../src/index.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/error.rs\n\n/**\n * Error types for Shamir secret sharing operations.\n *\n * Each variant mirrors a corresponding `Error::*` enum in\n * `bc-shamir-rust/src/error.rs` with the same trigger conditions and the\n * same default `Display` strings.\n *\n * Note on `InterpolationFailure`: this variant is **reserved but\n * unreachable** in both the Rust and TypeScript implementations.\n * `interpolate()` in `interpolate.ts` never actually returns / throws an\n * interpolation failure today — the Lagrange-basis math always succeeds\n * for any well-formed input. The variant is kept for forward\n * compatibility (e.g. should a future revision add input validation that\n * could reject pathological cases) and to keep the TS error type a 1:1\n * mirror of Rust's `Error` enum.\n */\nexport enum ShamirErrorType {\n SecretTooLong = \"SecretTooLong\",\n TooManyShares = \"TooManyShares\",\n /**\n * Reserved / unreachable in both Rust and TS today. See enum doc above.\n */\n InterpolationFailure = \"InterpolationFailure\",\n ChecksumFailure = \"ChecksumFailure\",\n SecretTooShort = \"SecretTooShort\",\n SecretNotEvenLen = \"SecretNotEvenLen\",\n InvalidThreshold = \"InvalidThreshold\",\n SharesUnequalLength = \"SharesUnequalLength\",\n}\n\n/**\n * Error class for Shamir secret sharing operations.\n */\nexport class ShamirError extends Error {\n readonly type: ShamirErrorType;\n\n constructor(type: ShamirErrorType, message?: string) {\n super(message ?? ShamirError.defaultMessage(type));\n this.type = type;\n this.name = \"ShamirError\";\n }\n\n private static defaultMessage(type: ShamirErrorType): string {\n switch (type) {\n case ShamirErrorType.SecretTooLong:\n return \"secret is too long\";\n case ShamirErrorType.TooManyShares:\n return \"too many shares\";\n case ShamirErrorType.InterpolationFailure:\n return \"interpolation failed\";\n case ShamirErrorType.ChecksumFailure:\n return \"checksum failure\";\n case ShamirErrorType.SecretTooShort:\n return \"secret is too short\";\n case ShamirErrorType.SecretNotEvenLen:\n return \"secret is not of even length\";\n case ShamirErrorType.InvalidThreshold:\n return \"invalid threshold\";\n case ShamirErrorType.SharesUnequalLength:\n return \"shares have unequal length\";\n }\n }\n}\n\n/**\n * Mirrors Rust's `Result<T, Error>` for API parity.\n *\n * The TypeScript port surfaces failures by throwing `ShamirError`\n * instances rather than returning a sum type, so this alias is a no-op\n * (`ShamirResult<T>` ≡ `T`). It is kept so signatures published in\n * `@bcts/shamir` remain visually parallel to their Rust counterparts.\n */\nexport type ShamirResult<T> = T;\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/hazmat.rs\n// GF(2^8) bitsliced polynomial operations for Shamir secret sharing.\n//\n// **Defensive arity guards.** Each helper here checks its array-length\n// preconditions (`r.length === 8`, `x.length >= 32`, …) and throws a\n// plain `Error` on violation. These guards mirror Rust's slice-indexing\n// `panic!` semantics — they signal an internal *contract violation*\n// (programmer error), not an end-user input error, and are deliberately\n// **not** elevated to `ShamirError`: that type carries variants for\n// recoverable, user-facing failures of the public `splitSecret` /\n// `recoverSecret` APIs, and has no variant matching \"wrong array arity\".\n// The public Shamir API never triggers these guards in normal use.\n\nimport { memzero } from \"@bcts/crypto\";\n\n/**\n * Internal contract guard. Mirrors a Rust `assert!(condition, message)`\n * panic on the boundary between hazmat helpers — kept as a bare `Error`\n * so it cannot be confused with a `ShamirError` from the public API.\n */\nfunction assertContract(condition: boolean, message: string): void {\n if (!condition) {\n throw new Error(message);\n }\n}\n\n/**\n * Convert an array of bytes into a bitsliced representation.\n * Takes the first 32 bytes from x and produces 8 u32 values.\n *\n * @param r - Output array of 8 u32 values (bitsliced representation)\n * @param x - Input array of at least 32 bytes\n */\nexport function bitslice(r: Uint32Array, x: Uint8Array): void {\n assertContract(x.length >= 32, \"bitslice: input must be at least 32 bytes\");\n assertContract(r.length === 8, \"bitslice: output must have 8 elements\");\n\n memzero(r);\n\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n const cur = x[arrIdx];\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n // r[bitIdx] |= ((cur & (1 << bitIdx)) >> bitIdx) << arrIdx\n r[bitIdx] |= ((cur & (1 << bitIdx)) >>> bitIdx) << arrIdx;\n }\n }\n}\n\n/**\n * Convert a bitsliced representation back to bytes.\n *\n * @param r - Output array of at least 32 bytes\n * @param x - Input array of 8 u32 values (bitsliced representation)\n */\nexport function unbitslice(r: Uint8Array, x: Uint32Array): void {\n assertContract(r.length >= 32, \"unbitslice: output must be at least 32 bytes\");\n assertContract(x.length === 8, \"unbitslice: input must have 8 elements\");\n\n memzero(r.subarray(0, 32));\n\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n const cur = x[bitIdx];\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n // r[arrIdx] |= ((cur & (1 << arrIdx)) >> arrIdx) << bitIdx\n r[arrIdx] |= ((cur & (1 << arrIdx)) >>> arrIdx) << bitIdx;\n }\n }\n}\n\n/**\n * Set all 32 positions in a bitsliced array to the same byte value.\n *\n * @param r - Output array of 8 u32 values\n * @param x - Byte value to set in all positions\n */\nexport function bitsliceSetall(r: Uint32Array, x: number): void {\n assertContract(r.length === 8, \"bitsliceSetall: output must have 8 elements\");\n\n for (let idx = 0; idx < 8; idx++) {\n // JavaScript needs special handling for the arithmetic right shift\n // This mirrors: *r = (((((x as u32) & (1u32.wrapping_shl(idx as u32)))\n // .wrapping_shl(31 - idx as u32)) as i32)\n // .wrapping_shr(31)) as u32;\n const bit = (x >>> idx) & 1;\n r[idx] = bit === 1 ? 0xffffffff : 0;\n }\n}\n\n/**\n * Add (XOR) r with x and store the result in r.\n * In GF(2^8), addition is XOR.\n *\n * @param r - First operand and result\n * @param x - Second operand\n */\nexport function gf256Add(r: Uint32Array, x: Uint32Array): void {\n assertContract(r.length === 8 && x.length === 8, \"gf256Add: arrays must have 8 elements\");\n\n for (let i = 0; i < 8; i++) {\n r[i] ^= x[i];\n }\n}\n\n/**\n * Safely multiply two bitsliced polynomials in GF(2^8) reduced by\n * x^8 + x^4 + x^3 + x + 1. r and a may overlap, but overlapping of r\n * and b will produce an incorrect result! If you need to square a polynomial\n * use gf256Square instead.\n *\n * @param r - Result array (8 u32 values)\n * @param a - First operand (may overlap with r)\n * @param b - Second operand (must NOT overlap with r)\n */\nexport function gf256Mul(r: Uint32Array, a: Uint32Array, b: Uint32Array): void {\n assertContract(\n r.length === 8 && a.length === 8 && b.length === 8,\n \"gf256Mul: arrays must have 8 elements\",\n );\n\n // Russian Peasant multiplication on two bitsliced polynomials\n const a2 = new Uint32Array(a);\n\n r[0] = a2[0] & b[0];\n r[1] = a2[1] & b[0];\n r[2] = a2[2] & b[0];\n r[3] = a2[3] & b[0];\n r[4] = a2[4] & b[0];\n r[5] = a2[5] & b[0];\n r[6] = a2[6] & b[0];\n r[7] = a2[7] & b[0];\n a2[0] ^= a2[7]; // reduce\n a2[2] ^= a2[7];\n a2[3] ^= a2[7];\n\n r[0] ^= a2[7] & b[1]; // add\n r[1] ^= a2[0] & b[1];\n r[2] ^= a2[1] & b[1];\n r[3] ^= a2[2] & b[1];\n r[4] ^= a2[3] & b[1];\n r[5] ^= a2[4] & b[1];\n r[6] ^= a2[5] & b[1];\n r[7] ^= a2[6] & b[1];\n a2[7] ^= a2[6]; // reduce\n a2[1] ^= a2[6];\n a2[2] ^= a2[6];\n\n r[0] ^= a2[6] & b[2]; // add\n r[1] ^= a2[7] & b[2];\n r[2] ^= a2[0] & b[2];\n r[3] ^= a2[1] & b[2];\n r[4] ^= a2[2] & b[2];\n r[5] ^= a2[3] & b[2];\n r[6] ^= a2[4] & b[2];\n r[7] ^= a2[5] & b[2];\n a2[6] ^= a2[5]; // reduce\n a2[0] ^= a2[5];\n a2[1] ^= a2[5];\n\n r[0] ^= a2[5] & b[3]; // add\n r[1] ^= a2[6] & b[3];\n r[2] ^= a2[7] & b[3];\n r[3] ^= a2[0] & b[3];\n r[4] ^= a2[1] & b[3];\n r[5] ^= a2[2] & b[3];\n r[6] ^= a2[3] & b[3];\n r[7] ^= a2[4] & b[3];\n a2[5] ^= a2[4]; // reduce\n a2[7] ^= a2[4];\n a2[0] ^= a2[4];\n\n r[0] ^= a2[4] & b[4]; // add\n r[1] ^= a2[5] & b[4];\n r[2] ^= a2[6] & b[4];\n r[3] ^= a2[7] & b[4];\n r[4] ^= a2[0] & b[4];\n r[5] ^= a2[1] & b[4];\n r[6] ^= a2[2] & b[4];\n r[7] ^= a2[3] & b[4];\n a2[4] ^= a2[3]; // reduce\n a2[6] ^= a2[3];\n a2[7] ^= a2[3];\n\n r[0] ^= a2[3] & b[5]; // add\n r[1] ^= a2[4] & b[5];\n r[2] ^= a2[5] & b[5];\n r[3] ^= a2[6] & b[5];\n r[4] ^= a2[7] & b[5];\n r[5] ^= a2[0] & b[5];\n r[6] ^= a2[1] & b[5];\n r[7] ^= a2[2] & b[5];\n a2[3] ^= a2[2]; // reduce\n a2[5] ^= a2[2];\n a2[6] ^= a2[2];\n\n r[0] ^= a2[2] & b[6]; // add\n r[1] ^= a2[3] & b[6];\n r[2] ^= a2[4] & b[6];\n r[3] ^= a2[5] & b[6];\n r[4] ^= a2[6] & b[6];\n r[5] ^= a2[7] & b[6];\n r[6] ^= a2[0] & b[6];\n r[7] ^= a2[1] & b[6];\n a2[2] ^= a2[1]; // reduce\n a2[4] ^= a2[1];\n a2[5] ^= a2[1];\n\n r[0] ^= a2[1] & b[7]; // add\n r[1] ^= a2[2] & b[7];\n r[2] ^= a2[3] & b[7];\n r[3] ^= a2[4] & b[7];\n r[4] ^= a2[5] & b[7];\n r[5] ^= a2[6] & b[7];\n r[6] ^= a2[7] & b[7];\n r[7] ^= a2[0] & b[7];\n}\n\n/**\n * Square x in GF(2^8) and write the result to r.\n * r and x may overlap.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to square\n */\nexport function gf256Square(r: Uint32Array, x: Uint32Array): void {\n assertContract(r.length === 8 && x.length === 8, \"gf256Square: arrays must have 8 elements\");\n\n // Use the Freshman's Dream rule to square the polynomial\n // Assignments are done from 7 downto 0, because this allows\n // in-place operation (e.g. gf256Square(r, r))\n const r14 = x[7];\n const r12 = x[6];\n let r10 = x[5];\n let r8 = x[4];\n r[6] = x[3];\n r[4] = x[2];\n r[2] = x[1];\n r[0] = x[0];\n\n // Reduce with x^8 + x^4 + x^3 + x + 1 until order is less than 8\n r[7] = r14; // r[7] was 0\n r[6] ^= r14;\n r10 ^= r14;\n // Skip, because r13 is always 0\n r[4] ^= r12;\n r[5] = r12; // r[5] was 0\n r[7] ^= r12;\n r8 ^= r12;\n // Skip, because r11 is always 0\n r[2] ^= r10;\n r[3] = r10; // r[3] was 0\n r[5] ^= r10;\n r[6] ^= r10;\n r[1] = r14; // r[1] was 0\n r[2] ^= r14; // Substitute r9 by r14 because they will always be equal\n r[4] ^= r14;\n r[5] ^= r14;\n r[0] ^= r8;\n r[1] ^= r8;\n r[3] ^= r8;\n r[4] ^= r8;\n}\n\n/**\n * Invert x in GF(2^8) and write the result to r.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to invert (will be modified)\n */\nexport function gf256Inv(r: Uint32Array, x: Uint32Array): void {\n assertContract(r.length === 8 && x.length === 8, \"gf256Inv: arrays must have 8 elements\");\n\n const y = new Uint32Array(8);\n const z = new Uint32Array(8);\n\n gf256Square(y, x); // y = x^2\n const y2 = new Uint32Array(y);\n gf256Square(y, y2); // y = x^4\n gf256Square(r, y); // r = x^8\n gf256Mul(z, r, x); // z = x^9\n const r2a = new Uint32Array(r);\n gf256Square(r, r2a); // r = x^16\n const r2b = new Uint32Array(r);\n gf256Mul(r, r2b, z); // r = x^25\n const r2c = new Uint32Array(r);\n gf256Square(r, r2c); // r = x^50\n gf256Square(z, r); // z = x^100\n const z2 = new Uint32Array(z);\n gf256Square(z, z2); // z = x^200\n const r2d = new Uint32Array(r);\n gf256Mul(r, r2d, z); // r = x^250\n const r2e = new Uint32Array(r);\n gf256Mul(r, r2e, y); // r = x^254\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/interpolate.rs\n\nimport { memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport { MAX_SECRET_LEN } from \"./index.js\";\nimport { bitslice, bitsliceSetall, gf256Add, gf256Inv, gf256Mul, unbitslice } from \"./hazmat.js\";\n\n/**\n * Calculate the lagrange basis coefficients for the lagrange polynomial\n * defined by the x coordinates xc at the value x.\n *\n * After the function runs, the values array should hold data satisfying:\n * --- (x-xc[j])\n * values[i] = | | -------------\n * j != i (xc[i]-xc[j])\n *\n * @param values - Output array for the lagrange basis values\n * @param n - Number of points (length of the xc array, 0 < n <= 32)\n * @param xc - Array of x components to use as interpolating points\n * @param x - x coordinate to evaluate lagrange polynomials at\n */\nfunction hazmatLagrangeBasis(values: Uint8Array, n: number, xc: Uint8Array, x: number): void {\n // call the contents of xc [ x0 x1 x2 ... xn-1 ]\n const xx = new Uint8Array(32 + 16);\n const xSlice = new Uint32Array(8);\n const lxi: Uint32Array[] = [];\n for (let i = 0; i < n; i++) {\n lxi.push(new Uint32Array(8));\n }\n const numerator = new Uint32Array(8);\n const denominator = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n xx.set(xc.subarray(0, n), 0);\n\n // xx now contains bitsliced [ x0 x1 x2 ... xn-1 0 0 0 ... ]\n for (let i = 0; i < n; i++) {\n // lxi = bitsliced [ xi xi+1 xi+2 ... xi-1 0 0 0 ]\n bitslice(lxi[i], xx.subarray(i));\n xx[i + n] = xx[i];\n }\n\n bitsliceSetall(xSlice, x);\n bitsliceSetall(numerator, 1);\n bitsliceSetall(denominator, 1);\n\n for (let i = 1; i < n; i++) {\n temp.set(xSlice);\n gf256Add(temp, lxi[i]);\n // temp = [ x-xi+i x-xi+2 x-xi+3 ... x-xi x x x]\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n temp.set(lxi[0]);\n gf256Add(temp, lxi[i]);\n // temp = [x0-xi+1 x1-xi+1 x2-xi+2 ... xn-x0 0 0 0]\n const denominator2 = new Uint32Array(denominator);\n gf256Mul(denominator, denominator2, temp);\n }\n\n // At this stage the numerator contains\n // [ num0 num1 num2 ... numn 0 0 0]\n //\n // where numi = prod(j, j!=i, x-xj )\n //\n // and the denominator contains\n // [ d0 d1 d2 ... dn 0 0 0]\n //\n // where di = prod(j, j!=i, xi-xj)\n\n gf256Inv(temp, denominator);\n\n // gf256_inv uses exponentiation to calculate inverse, so the zeros end up\n // remaining zeros.\n\n // tmp = [ 1/d0 1/d1 1/d2 ... 1/dn 0 0 0]\n\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n // numerator now contains [ l_n_0(x) l_n_1(x) ... l_n_n-1(x) 0 0 0]\n // use the xx array to unpack it\n\n unbitslice(xx, numerator);\n\n // copy results to output array\n values.set(xx.subarray(0, n), 0);\n}\n\n/**\n * Safely interpolate the polynomial going through\n * the points (x0 [y0_0 y0_1 y0_2 ... y0_31]) , (x1 [y1_0 ...]), ...\n *\n * where\n * xi points to [x0 x1 ... xn-1 ]\n * y contains an array of pointers to 32-bit arrays of y values\n * y contains [y0 y1 y2 ... yn-1]\n * and each of the yi arrays contain [yi_0 yi_i ... yi_31].\n *\n * @param n - Number of points to interpolate\n * @param xi - x coordinates for points (array of length n)\n * @param yl - Length of y coordinate arrays\n * @param yij - Array of n arrays of length yl\n * @param x - Coordinate to interpolate at\n * @returns The interpolated result of length yl\n */\nexport function interpolate(\n n: number,\n xi: Uint8Array,\n yl: number,\n yij: Uint8Array[],\n x: number,\n): Uint8Array {\n // The hazmat gf256 implementation needs the y-coordinate data\n // to be in 32-byte blocks\n const y: Uint8Array[] = [];\n for (let i = 0; i < n; i++) {\n y.push(new Uint8Array(MAX_SECRET_LEN));\n }\n const values = new Uint8Array(MAX_SECRET_LEN);\n\n for (let i = 0; i < n; i++) {\n y[i].set(yij[i].subarray(0, yl), 0);\n }\n\n const lagrange = new Uint8Array(n);\n const ySlice = new Uint32Array(8);\n const resultSlice = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n hazmatLagrangeBasis(lagrange, n, xi, x);\n\n bitsliceSetall(resultSlice, 0);\n\n for (let i = 0; i < n; i++) {\n bitslice(ySlice, y[i]);\n bitsliceSetall(temp, lagrange[i]);\n const temp2 = new Uint32Array(temp);\n gf256Mul(temp, temp2, ySlice);\n gf256Add(resultSlice, temp);\n }\n\n unbitslice(values, resultSlice);\n\n // the calling code is only expecting yl bytes back\n const result = new Uint8Array(yl);\n result.set(values.subarray(0, yl), 0);\n\n // clean up stack\n memzero(lagrange);\n memzero(ySlice);\n memzero(resultSlice);\n memzero(temp);\n memzeroVecVecU8(y);\n memzero(values);\n\n return result;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/shamir.rs\n\nimport { hmacSha256, memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\n\nimport { ShamirError, ShamirErrorType } from \"./error.js\";\nimport { MAX_SECRET_LEN, MAX_SHARE_COUNT, MIN_SECRET_LEN } from \"./index.js\";\nimport { interpolate } from \"./interpolate.js\";\n\nconst SECRET_INDEX = 255;\nconst DIGEST_INDEX = 254;\n\nfunction createDigest(randomData: Uint8Array, sharedSecret: Uint8Array): Uint8Array {\n return hmacSha256(randomData, sharedSecret);\n}\n\nfunction validateParameters(threshold: number, shareCount: number, secretLength: number): void {\n if (shareCount > MAX_SHARE_COUNT) {\n throw new ShamirError(ShamirErrorType.TooManyShares);\n } else if (threshold < 1 || threshold > shareCount) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n } else if (secretLength > MAX_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooLong);\n } else if (secretLength < MIN_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooShort);\n } else if ((secretLength & 1) !== 0) {\n throw new ShamirError(ShamirErrorType.SecretNotEvenLen);\n }\n}\n\n/**\n * Splits a secret into shares using the Shamir secret sharing algorithm.\n *\n * @param threshold - The minimum number of shares required to reconstruct the\n * secret. Must be greater than or equal to 1 and less than or equal to\n * shareCount.\n * @param shareCount - The total number of shares to generate. Must be at least\n * threshold and less than or equal to MAX_SHARE_COUNT.\n * @param secret - A Uint8Array containing the secret to be split. Must be at\n * least MIN_SECRET_LEN bytes long and at most MAX_SECRET_LEN bytes long.\n * The length must be an even number.\n * @param randomGenerator - An implementation of the RandomNumberGenerator\n * interface, used to generate random data.\n * @returns An array of Uint8Array representing the shares of the secret.\n * @throws ShamirError if parameters are invalid\n *\n * @example\n * ```typescript\n * import { splitSecret } from \"@bcts/shamir\";\n * import { SecureRandomNumberGenerator } from \"@bcts/rand\";\n *\n * const threshold = 2;\n * const shareCount = 3;\n * const secret = new TextEncoder().encode(\"my secret belongs to me.\");\n * const rng = new SecureRandomNumberGenerator();\n *\n * const shares = splitSecret(threshold, shareCount, secret, rng);\n * console.log(shares.length); // 3\n * ```\n */\nexport function splitSecret(\n threshold: number,\n shareCount: number,\n secret: Uint8Array,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[] {\n validateParameters(threshold, shareCount, secret.length);\n\n if (threshold === 1) {\n // just return shareCount copies of the secret\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret));\n }\n return result;\n } else {\n const x = new Uint8Array(shareCount);\n const y: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n y.push(new Uint8Array(secret.length));\n }\n let n = 0;\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret.length));\n }\n\n for (let index = 0; index < threshold - 2; index++) {\n randomGenerator.fillRandomData(result[index]);\n x[n] = index;\n y[n].set(result[index]);\n n++;\n }\n\n // generate secret_length - 4 bytes worth of random data\n const digest = new Uint8Array(secret.length);\n randomGenerator.fillRandomData(digest.subarray(4));\n // put 4 bytes of digest at the top of the digest array\n const d = createDigest(digest.subarray(4), secret);\n digest.set(d.subarray(0, 4), 0);\n x[n] = DIGEST_INDEX;\n y[n].set(digest);\n n++;\n\n x[n] = SECRET_INDEX;\n y[n].set(secret);\n n++;\n\n for (let index = threshold - 2; index < shareCount; index++) {\n const v = interpolate(n, x, secret.length, y, index);\n result[index].set(v);\n }\n\n // clean up stack\n memzero(digest);\n memzero(x);\n memzeroVecVecU8(y);\n\n return result;\n }\n}\n\n/**\n * Recovers the secret from the given shares using the Shamir secret sharing\n * algorithm.\n *\n * @param indexes - An array of indexes of the shares to be used for recovering\n * the secret. These are the indexes of the shares returned by splitSecret.\n * @param shares - An array of shares of the secret matching the indexes in\n * indexes. These are the shares returned by splitSecret.\n * @returns A Uint8Array representing the recovered secret.\n * @throws ShamirError if parameters are invalid or checksum verification fails\n *\n * @example\n * ```typescript\n * import { recoverSecret } from \"@bcts/shamir\";\n *\n * const indexes = [0, 2];\n * const shares = [\n * new Uint8Array([47, 165, 102, 232, ...]),\n * new Uint8Array([221, 174, 116, 201, ...]),\n * ];\n *\n * const secret = recoverSecret(indexes, shares);\n * console.log(new TextDecoder().decode(secret)); // \"my secret belongs to me.\"\n * ```\n */\nexport function recoverSecret(indexes: number[], shares: Uint8Array[]): Uint8Array {\n const threshold = shares.length;\n if (threshold === 0 || indexes.length !== threshold) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n }\n\n const shareLength = shares[0].length;\n validateParameters(threshold, threshold, shareLength);\n\n const allSameLength = shares.every((share) => share.length === shareLength);\n if (!allSameLength) {\n throw new ShamirError(ShamirErrorType.SharesUnequalLength);\n }\n\n if (threshold === 1) {\n return new Uint8Array(shares[0]);\n } else {\n const indexesU8 = new Uint8Array(indexes);\n\n const digest = interpolate(threshold, indexesU8, shareLength, shares, DIGEST_INDEX);\n const secret = interpolate(threshold, indexesU8, shareLength, shares, SECRET_INDEX);\n const verify = createDigest(digest.subarray(4), secret);\n\n let valid = true;\n for (let i = 0; i < 4; i++) {\n valid = valid && digest[i] === verify[i];\n }\n\n memzero(digest);\n memzero(verify);\n\n if (!valid) {\n throw new ShamirError(ShamirErrorType.ChecksumFailure);\n }\n\n return secret;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Blockchain Commons Shamir Secret Sharing\n// Ported from bc-shamir-rust\n//\n// This is a pure TypeScript implementation of Shamir's Secret Sharing (SSS),\n// a cryptographic technique in which a secret is divided into parts, called\n// shares, in such a way that a threshold of several shares are needed to\n// reconstruct the secret. The shares are distributed in a way that makes it\n// impossible for an attacker to know anything about the secret without having\n// a threshold of shares. If the number of shares is less than the threshold,\n// then no information about the secret is revealed.\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = 16;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = 32;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = 16;\n\n// Error types\nexport { ShamirError, ShamirErrorType, type ShamirResult } from \"./error.js\";\n\n// Main functions\nexport { splitSecret, recoverSecret } from \"./shamir.js\";\n"],"mappings":"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,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AACZ,KAAG,MAAM,GAAG;AAEZ,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAE,MAAM,GAAG,KAA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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,19 +1,39 @@
|
|
|
1
1
|
import { hmacSha256, memzero, memzeroVecVecU8 } from "@bcts/crypto";
|
|
2
|
-
|
|
3
2
|
//#region src/error.ts
|
|
4
3
|
/**
|
|
4
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
5
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6
|
+
*
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
5
9
|
* Error types for Shamir secret sharing operations.
|
|
10
|
+
*
|
|
11
|
+
* Each variant mirrors a corresponding `Error::*` enum in
|
|
12
|
+
* `bc-shamir-rust/src/error.rs` with the same trigger conditions and the
|
|
13
|
+
* same default `Display` strings.
|
|
14
|
+
*
|
|
15
|
+
* Note on `InterpolationFailure`: this variant is **reserved but
|
|
16
|
+
* unreachable** in both the Rust and TypeScript implementations.
|
|
17
|
+
* `interpolate()` in `interpolate.ts` never actually returns / throws an
|
|
18
|
+
* interpolation failure today — the Lagrange-basis math always succeeds
|
|
19
|
+
* for any well-formed input. The variant is kept for forward
|
|
20
|
+
* compatibility (e.g. should a future revision add input validation that
|
|
21
|
+
* could reject pathological cases) and to keep the TS error type a 1:1
|
|
22
|
+
* mirror of Rust's `Error` enum.
|
|
6
23
|
*/
|
|
7
|
-
let ShamirErrorType = /* @__PURE__ */ function(ShamirErrorType
|
|
8
|
-
ShamirErrorType
|
|
9
|
-
ShamirErrorType
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
ShamirErrorType
|
|
14
|
-
ShamirErrorType
|
|
15
|
-
ShamirErrorType
|
|
16
|
-
|
|
24
|
+
let ShamirErrorType = /* @__PURE__ */ function(ShamirErrorType) {
|
|
25
|
+
ShamirErrorType["SecretTooLong"] = "SecretTooLong";
|
|
26
|
+
ShamirErrorType["TooManyShares"] = "TooManyShares";
|
|
27
|
+
/**
|
|
28
|
+
* Reserved / unreachable in both Rust and TS today. See enum doc above.
|
|
29
|
+
*/
|
|
30
|
+
ShamirErrorType["InterpolationFailure"] = "InterpolationFailure";
|
|
31
|
+
ShamirErrorType["ChecksumFailure"] = "ChecksumFailure";
|
|
32
|
+
ShamirErrorType["SecretTooShort"] = "SecretTooShort";
|
|
33
|
+
ShamirErrorType["SecretNotEvenLen"] = "SecretNotEvenLen";
|
|
34
|
+
ShamirErrorType["InvalidThreshold"] = "InvalidThreshold";
|
|
35
|
+
ShamirErrorType["SharesUnequalLength"] = "SharesUnequalLength";
|
|
36
|
+
return ShamirErrorType;
|
|
17
37
|
}({});
|
|
18
38
|
/**
|
|
19
39
|
* Error class for Shamir secret sharing operations.
|
|
@@ -27,21 +47,33 @@ var ShamirError = class ShamirError extends Error {
|
|
|
27
47
|
}
|
|
28
48
|
static defaultMessage(type) {
|
|
29
49
|
switch (type) {
|
|
30
|
-
case
|
|
31
|
-
case
|
|
32
|
-
case
|
|
33
|
-
case
|
|
34
|
-
case
|
|
35
|
-
case
|
|
36
|
-
case
|
|
37
|
-
case
|
|
50
|
+
case "SecretTooLong": return "secret is too long";
|
|
51
|
+
case "TooManyShares": return "too many shares";
|
|
52
|
+
case "InterpolationFailure": return "interpolation failed";
|
|
53
|
+
case "ChecksumFailure": return "checksum failure";
|
|
54
|
+
case "SecretTooShort": return "secret is too short";
|
|
55
|
+
case "SecretNotEvenLen": return "secret is not of even length";
|
|
56
|
+
case "InvalidThreshold": return "invalid threshold";
|
|
57
|
+
case "SharesUnequalLength": return "shares have unequal length";
|
|
38
58
|
}
|
|
39
59
|
}
|
|
40
60
|
};
|
|
41
|
-
|
|
42
61
|
//#endregion
|
|
43
62
|
//#region src/hazmat.ts
|
|
44
63
|
/**
|
|
64
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
65
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
66
|
+
*
|
|
67
|
+
*/
|
|
68
|
+
/**
|
|
69
|
+
* Internal contract guard. Mirrors a Rust `assert!(condition, message)`
|
|
70
|
+
* panic on the boundary between hazmat helpers — kept as a bare `Error`
|
|
71
|
+
* so it cannot be confused with a `ShamirError` from the public API.
|
|
72
|
+
*/
|
|
73
|
+
function assertContract(condition, message) {
|
|
74
|
+
if (!condition) throw new Error(message);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
45
77
|
* Convert an array of bytes into a bitsliced representation.
|
|
46
78
|
* Takes the first 32 bytes from x and produces 8 u32 values.
|
|
47
79
|
*
|
|
@@ -49,8 +81,8 @@ var ShamirError = class ShamirError extends Error {
|
|
|
49
81
|
* @param x - Input array of at least 32 bytes
|
|
50
82
|
*/
|
|
51
83
|
function bitslice(r, x) {
|
|
52
|
-
|
|
53
|
-
|
|
84
|
+
assertContract(x.length >= 32, "bitslice: input must be at least 32 bytes");
|
|
85
|
+
assertContract(r.length === 8, "bitslice: output must have 8 elements");
|
|
54
86
|
memzero(r);
|
|
55
87
|
for (let arrIdx = 0; arrIdx < 32; arrIdx++) {
|
|
56
88
|
const cur = x[arrIdx];
|
|
@@ -64,8 +96,8 @@ function bitslice(r, x) {
|
|
|
64
96
|
* @param x - Input array of 8 u32 values (bitsliced representation)
|
|
65
97
|
*/
|
|
66
98
|
function unbitslice(r, x) {
|
|
67
|
-
|
|
68
|
-
|
|
99
|
+
assertContract(r.length >= 32, "unbitslice: output must be at least 32 bytes");
|
|
100
|
+
assertContract(x.length === 8, "unbitslice: input must have 8 elements");
|
|
69
101
|
memzero(r.subarray(0, 32));
|
|
70
102
|
for (let bitIdx = 0; bitIdx < 8; bitIdx++) {
|
|
71
103
|
const cur = x[bitIdx];
|
|
@@ -79,7 +111,7 @@ function unbitslice(r, x) {
|
|
|
79
111
|
* @param x - Byte value to set in all positions
|
|
80
112
|
*/
|
|
81
113
|
function bitsliceSetall(r, x) {
|
|
82
|
-
|
|
114
|
+
assertContract(r.length === 8, "bitsliceSetall: output must have 8 elements");
|
|
83
115
|
for (let idx = 0; idx < 8; idx++) r[idx] = (x >>> idx & 1) === 1 ? 4294967295 : 0;
|
|
84
116
|
}
|
|
85
117
|
/**
|
|
@@ -90,7 +122,7 @@ function bitsliceSetall(r, x) {
|
|
|
90
122
|
* @param x - Second operand
|
|
91
123
|
*/
|
|
92
124
|
function gf256Add(r, x) {
|
|
93
|
-
|
|
125
|
+
assertContract(r.length === 8 && x.length === 8, "gf256Add: arrays must have 8 elements");
|
|
94
126
|
for (let i = 0; i < 8; i++) r[i] ^= x[i];
|
|
95
127
|
}
|
|
96
128
|
/**
|
|
@@ -104,7 +136,7 @@ function gf256Add(r, x) {
|
|
|
104
136
|
* @param b - Second operand (must NOT overlap with r)
|
|
105
137
|
*/
|
|
106
138
|
function gf256Mul(r, a, b) {
|
|
107
|
-
|
|
139
|
+
assertContract(r.length === 8 && a.length === 8 && b.length === 8, "gf256Mul: arrays must have 8 elements");
|
|
108
140
|
const a2 = new Uint32Array(a);
|
|
109
141
|
r[0] = a2[0] & b[0];
|
|
110
142
|
r[1] = a2[1] & b[0];
|
|
@@ -200,7 +232,7 @@ function gf256Mul(r, a, b) {
|
|
|
200
232
|
* @param x - Value to square
|
|
201
233
|
*/
|
|
202
234
|
function gf256Square(r, x) {
|
|
203
|
-
|
|
235
|
+
assertContract(r.length === 8 && x.length === 8, "gf256Square: arrays must have 8 elements");
|
|
204
236
|
const r14 = x[7];
|
|
205
237
|
const r12 = x[6];
|
|
206
238
|
let r10 = x[5];
|
|
@@ -236,7 +268,7 @@ function gf256Square(r, x) {
|
|
|
236
268
|
* @param x - Value to invert (will be modified)
|
|
237
269
|
*/
|
|
238
270
|
function gf256Inv(r, x) {
|
|
239
|
-
|
|
271
|
+
assertContract(r.length === 8 && x.length === 8, "gf256Inv: arrays must have 8 elements");
|
|
240
272
|
const y = new Uint32Array(8);
|
|
241
273
|
const z = new Uint32Array(8);
|
|
242
274
|
gf256Square(y, x);
|
|
@@ -251,10 +283,14 @@ function gf256Inv(r, x) {
|
|
|
251
283
|
gf256Mul(r, new Uint32Array(r), z);
|
|
252
284
|
gf256Mul(r, new Uint32Array(r), y);
|
|
253
285
|
}
|
|
254
|
-
|
|
255
286
|
//#endregion
|
|
256
287
|
//#region src/interpolate.ts
|
|
257
288
|
/**
|
|
289
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
290
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
291
|
+
*
|
|
292
|
+
*/
|
|
293
|
+
/**
|
|
258
294
|
* Calculate the lagrange basis coefficients for the lagrange polynomial
|
|
259
295
|
* defined by the x coordinates xc at the value x.
|
|
260
296
|
*
|
|
@@ -316,8 +352,8 @@ function hazmatLagrangeBasis(values, n, xc, x) {
|
|
|
316
352
|
*/
|
|
317
353
|
function interpolate(n, xi, yl, yij, x) {
|
|
318
354
|
const y = [];
|
|
319
|
-
for (let i = 0; i < n; i++) y.push(new Uint8Array(
|
|
320
|
-
const values = new Uint8Array(
|
|
355
|
+
for (let i = 0; i < n; i++) y.push(new Uint8Array(32));
|
|
356
|
+
const values = new Uint8Array(32);
|
|
321
357
|
for (let i = 0; i < n; i++) y[i].set(yij[i].subarray(0, yl), 0);
|
|
322
358
|
const lagrange = new Uint8Array(n);
|
|
323
359
|
const ySlice = new Uint32Array(8);
|
|
@@ -342,20 +378,24 @@ function interpolate(n, xi, yl, yij, x) {
|
|
|
342
378
|
memzero(values);
|
|
343
379
|
return result;
|
|
344
380
|
}
|
|
345
|
-
|
|
346
381
|
//#endregion
|
|
347
382
|
//#region src/shamir.ts
|
|
383
|
+
/**
|
|
384
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
385
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
386
|
+
*
|
|
387
|
+
*/
|
|
348
388
|
const SECRET_INDEX = 255;
|
|
349
389
|
const DIGEST_INDEX = 254;
|
|
350
390
|
function createDigest(randomData, sharedSecret) {
|
|
351
391
|
return hmacSha256(randomData, sharedSecret);
|
|
352
392
|
}
|
|
353
393
|
function validateParameters(threshold, shareCount, secretLength) {
|
|
354
|
-
if (shareCount >
|
|
355
|
-
else if (threshold < 1 || threshold > shareCount) throw new ShamirError(
|
|
356
|
-
else if (secretLength >
|
|
357
|
-
else if (secretLength <
|
|
358
|
-
else if ((secretLength & 1) !== 0) throw new ShamirError(
|
|
394
|
+
if (shareCount > 16) throw new ShamirError("TooManyShares");
|
|
395
|
+
else if (threshold < 1 || threshold > shareCount) throw new ShamirError("InvalidThreshold");
|
|
396
|
+
else if (secretLength > 32) throw new ShamirError("SecretTooLong");
|
|
397
|
+
else if (secretLength < 16) throw new ShamirError("SecretTooShort");
|
|
398
|
+
else if ((secretLength & 1) !== 0) throw new ShamirError("SecretNotEvenLen");
|
|
359
399
|
}
|
|
360
400
|
/**
|
|
361
401
|
* Splits a secret into shares using the Shamir secret sharing algorithm.
|
|
@@ -453,10 +493,10 @@ function splitSecret(threshold, shareCount, secret, randomGenerator) {
|
|
|
453
493
|
*/
|
|
454
494
|
function recoverSecret(indexes, shares) {
|
|
455
495
|
const threshold = shares.length;
|
|
456
|
-
if (threshold === 0 || indexes.length !== threshold) throw new ShamirError(
|
|
496
|
+
if (threshold === 0 || indexes.length !== threshold) throw new ShamirError("InvalidThreshold");
|
|
457
497
|
const shareLength = shares[0].length;
|
|
458
498
|
validateParameters(threshold, threshold, shareLength);
|
|
459
|
-
if (!shares.every((share) => share.length === shareLength)) throw new ShamirError(
|
|
499
|
+
if (!shares.every((share) => share.length === shareLength)) throw new ShamirError("SharesUnequalLength");
|
|
460
500
|
if (threshold === 1) return new Uint8Array(shares[0]);
|
|
461
501
|
else {
|
|
462
502
|
const indexesU8 = new Uint8Array(indexes);
|
|
@@ -467,14 +507,18 @@ function recoverSecret(indexes, shares) {
|
|
|
467
507
|
for (let i = 0; i < 4; i++) valid = valid && digest[i] === verify[i];
|
|
468
508
|
memzero(digest);
|
|
469
509
|
memzero(verify);
|
|
470
|
-
if (!valid) throw new ShamirError(
|
|
510
|
+
if (!valid) throw new ShamirError("ChecksumFailure");
|
|
471
511
|
return secret;
|
|
472
512
|
}
|
|
473
513
|
}
|
|
474
|
-
|
|
475
514
|
//#endregion
|
|
476
515
|
//#region src/index.ts
|
|
477
516
|
/**
|
|
517
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
518
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
519
|
+
*
|
|
520
|
+
*/
|
|
521
|
+
/**
|
|
478
522
|
* The minimum length of a secret.
|
|
479
523
|
*/
|
|
480
524
|
const MIN_SECRET_LEN = 16;
|
|
@@ -486,7 +530,7 @@ const MAX_SECRET_LEN = 32;
|
|
|
486
530
|
* The maximum number of shares that can be generated from a secret.
|
|
487
531
|
*/
|
|
488
532
|
const MAX_SHARE_COUNT = 16;
|
|
489
|
-
|
|
490
533
|
//#endregion
|
|
491
|
-
export { MAX_SECRET_LEN, MAX_SHARE_COUNT, MIN_SECRET_LEN, ShamirError, ShamirErrorType,
|
|
534
|
+
export { MAX_SECRET_LEN, MAX_SHARE_COUNT, MIN_SECRET_LEN, ShamirError, ShamirErrorType, recoverSecret, splitSecret };
|
|
535
|
+
|
|
492
536
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["lxi: Uint32Array[]","y: Uint8Array[]","result: Uint8Array[]","y: Uint8Array[]"],"sources":["../src/error.ts","../src/hazmat.ts","../src/interpolate.ts","../src/shamir.ts","../src/index.ts"],"sourcesContent":["// Ported from bc-shamir-rust/src/error.rs\n\n/**\n * Error types for Shamir secret sharing operations.\n */\nexport enum ShamirErrorType {\n SecretTooLong = \"SecretTooLong\",\n TooManyShares = \"TooManyShares\",\n InterpolationFailure = \"InterpolationFailure\",\n ChecksumFailure = \"ChecksumFailure\",\n SecretTooShort = \"SecretTooShort\",\n SecretNotEvenLen = \"SecretNotEvenLen\",\n InvalidThreshold = \"InvalidThreshold\",\n SharesUnequalLength = \"SharesUnequalLength\",\n}\n\n/**\n * Error class for Shamir secret sharing operations.\n */\nexport class ShamirError extends Error {\n readonly type: ShamirErrorType;\n\n constructor(type: ShamirErrorType, message?: string) {\n super(message ?? ShamirError.defaultMessage(type));\n this.type = type;\n this.name = \"ShamirError\";\n }\n\n private static defaultMessage(type: ShamirErrorType): string {\n switch (type) {\n case ShamirErrorType.SecretTooLong:\n return \"secret is too long\";\n case ShamirErrorType.TooManyShares:\n return \"too many shares\";\n case ShamirErrorType.InterpolationFailure:\n return \"interpolation failed\";\n case ShamirErrorType.ChecksumFailure:\n return \"checksum failure\";\n case ShamirErrorType.SecretTooShort:\n return \"secret is too short\";\n case ShamirErrorType.SecretNotEvenLen:\n return \"secret is not of even length\";\n case ShamirErrorType.InvalidThreshold:\n return \"invalid threshold\";\n case ShamirErrorType.SharesUnequalLength:\n return \"shares have unequal length\";\n }\n }\n}\n\nexport type ShamirResult<T> = T;\n","// Ported from bc-shamir-rust/src/hazmat.rs\n// GF(2^8) bitsliced polynomial operations for Shamir secret sharing\n\nimport { memzero } from \"@bcts/crypto\";\n\n/**\n * Convert an array of bytes into a bitsliced representation.\n * Takes the first 32 bytes from x and produces 8 u32 values.\n *\n * @param r - Output array of 8 u32 values (bitsliced representation)\n * @param x - Input array of at least 32 bytes\n */\nexport function bitslice(r: Uint32Array, x: Uint8Array): void {\n if (x.length < 32) {\n throw new Error(\"bitslice: input must be at least 32 bytes\");\n }\n if (r.length !== 8) {\n throw new Error(\"bitslice: output must have 8 elements\");\n }\n\n memzero(r);\n\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n const cur = x[arrIdx];\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n // r[bitIdx] |= ((cur & (1 << bitIdx)) >> bitIdx) << arrIdx\n r[bitIdx] |= ((cur & (1 << bitIdx)) >>> bitIdx) << arrIdx;\n }\n }\n}\n\n/**\n * Convert a bitsliced representation back to bytes.\n *\n * @param r - Output array of at least 32 bytes\n * @param x - Input array of 8 u32 values (bitsliced representation)\n */\nexport function unbitslice(r: Uint8Array, x: Uint32Array): void {\n if (r.length < 32) {\n throw new Error(\"unbitslice: output must be at least 32 bytes\");\n }\n if (x.length !== 8) {\n throw new Error(\"unbitslice: input must have 8 elements\");\n }\n\n memzero(r.subarray(0, 32));\n\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n const cur = x[bitIdx];\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n // r[arrIdx] |= ((cur & (1 << arrIdx)) >> arrIdx) << bitIdx\n r[arrIdx] |= ((cur & (1 << arrIdx)) >>> arrIdx) << bitIdx;\n }\n }\n}\n\n/**\n * Set all 32 positions in a bitsliced array to the same byte value.\n *\n * @param r - Output array of 8 u32 values\n * @param x - Byte value to set in all positions\n */\nexport function bitsliceSetall(r: Uint32Array, x: number): void {\n if (r.length !== 8) {\n throw new Error(\"bitsliceSetall: output must have 8 elements\");\n }\n\n for (let idx = 0; idx < 8; idx++) {\n // JavaScript needs special handling for the arithmetic right shift\n // This mirrors: *r = (((((x as u32) & (1u32.wrapping_shl(idx as u32)))\n // .wrapping_shl(31 - idx as u32)) as i32)\n // .wrapping_shr(31)) as u32;\n const bit = (x >>> idx) & 1;\n r[idx] = bit === 1 ? 0xffffffff : 0;\n }\n}\n\n/**\n * Add (XOR) r with x and store the result in r.\n * In GF(2^8), addition is XOR.\n *\n * @param r - First operand and result\n * @param x - Second operand\n */\nexport function gf256Add(r: Uint32Array, x: Uint32Array): void {\n if (r.length !== 8 || x.length !== 8) {\n throw new Error(\"gf256Add: arrays must have 8 elements\");\n }\n\n for (let i = 0; i < 8; i++) {\n r[i] ^= x[i];\n }\n}\n\n/**\n * Safely multiply two bitsliced polynomials in GF(2^8) reduced by\n * x^8 + x^4 + x^3 + x + 1. r and a may overlap, but overlapping of r\n * and b will produce an incorrect result! If you need to square a polynomial\n * use gf256Square instead.\n *\n * @param r - Result array (8 u32 values)\n * @param a - First operand (may overlap with r)\n * @param b - Second operand (must NOT overlap with r)\n */\nexport function gf256Mul(r: Uint32Array, a: Uint32Array, b: Uint32Array): void {\n if (r.length !== 8 || a.length !== 8 || b.length !== 8) {\n throw new Error(\"gf256Mul: arrays must have 8 elements\");\n }\n\n // Russian Peasant multiplication on two bitsliced polynomials\n const a2 = new Uint32Array(a);\n\n r[0] = a2[0] & b[0];\n r[1] = a2[1] & b[0];\n r[2] = a2[2] & b[0];\n r[3] = a2[3] & b[0];\n r[4] = a2[4] & b[0];\n r[5] = a2[5] & b[0];\n r[6] = a2[6] & b[0];\n r[7] = a2[7] & b[0];\n a2[0] ^= a2[7]; // reduce\n a2[2] ^= a2[7];\n a2[3] ^= a2[7];\n\n r[0] ^= a2[7] & b[1]; // add\n r[1] ^= a2[0] & b[1];\n r[2] ^= a2[1] & b[1];\n r[3] ^= a2[2] & b[1];\n r[4] ^= a2[3] & b[1];\n r[5] ^= a2[4] & b[1];\n r[6] ^= a2[5] & b[1];\n r[7] ^= a2[6] & b[1];\n a2[7] ^= a2[6]; // reduce\n a2[1] ^= a2[6];\n a2[2] ^= a2[6];\n\n r[0] ^= a2[6] & b[2]; // add\n r[1] ^= a2[7] & b[2];\n r[2] ^= a2[0] & b[2];\n r[3] ^= a2[1] & b[2];\n r[4] ^= a2[2] & b[2];\n r[5] ^= a2[3] & b[2];\n r[6] ^= a2[4] & b[2];\n r[7] ^= a2[5] & b[2];\n a2[6] ^= a2[5]; // reduce\n a2[0] ^= a2[5];\n a2[1] ^= a2[5];\n\n r[0] ^= a2[5] & b[3]; // add\n r[1] ^= a2[6] & b[3];\n r[2] ^= a2[7] & b[3];\n r[3] ^= a2[0] & b[3];\n r[4] ^= a2[1] & b[3];\n r[5] ^= a2[2] & b[3];\n r[6] ^= a2[3] & b[3];\n r[7] ^= a2[4] & b[3];\n a2[5] ^= a2[4]; // reduce\n a2[7] ^= a2[4];\n a2[0] ^= a2[4];\n\n r[0] ^= a2[4] & b[4]; // add\n r[1] ^= a2[5] & b[4];\n r[2] ^= a2[6] & b[4];\n r[3] ^= a2[7] & b[4];\n r[4] ^= a2[0] & b[4];\n r[5] ^= a2[1] & b[4];\n r[6] ^= a2[2] & b[4];\n r[7] ^= a2[3] & b[4];\n a2[4] ^= a2[3]; // reduce\n a2[6] ^= a2[3];\n a2[7] ^= a2[3];\n\n r[0] ^= a2[3] & b[5]; // add\n r[1] ^= a2[4] & b[5];\n r[2] ^= a2[5] & b[5];\n r[3] ^= a2[6] & b[5];\n r[4] ^= a2[7] & b[5];\n r[5] ^= a2[0] & b[5];\n r[6] ^= a2[1] & b[5];\n r[7] ^= a2[2] & b[5];\n a2[3] ^= a2[2]; // reduce\n a2[5] ^= a2[2];\n a2[6] ^= a2[2];\n\n r[0] ^= a2[2] & b[6]; // add\n r[1] ^= a2[3] & b[6];\n r[2] ^= a2[4] & b[6];\n r[3] ^= a2[5] & b[6];\n r[4] ^= a2[6] & b[6];\n r[5] ^= a2[7] & b[6];\n r[6] ^= a2[0] & b[6];\n r[7] ^= a2[1] & b[6];\n a2[2] ^= a2[1]; // reduce\n a2[4] ^= a2[1];\n a2[5] ^= a2[1];\n\n r[0] ^= a2[1] & b[7]; // add\n r[1] ^= a2[2] & b[7];\n r[2] ^= a2[3] & b[7];\n r[3] ^= a2[4] & b[7];\n r[4] ^= a2[5] & b[7];\n r[5] ^= a2[6] & b[7];\n r[6] ^= a2[7] & b[7];\n r[7] ^= a2[0] & b[7];\n}\n\n/**\n * Square x in GF(2^8) and write the result to r.\n * r and x may overlap.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to square\n */\nexport function gf256Square(r: Uint32Array, x: Uint32Array): void {\n if (r.length !== 8 || x.length !== 8) {\n throw new Error(\"gf256Square: arrays must have 8 elements\");\n }\n\n // Use the Freshman's Dream rule to square the polynomial\n // Assignments are done from 7 downto 0, because this allows\n // in-place operation (e.g. gf256Square(r, r))\n const r14 = x[7];\n const r12 = x[6];\n let r10 = x[5];\n let r8 = x[4];\n r[6] = x[3];\n r[4] = x[2];\n r[2] = x[1];\n r[0] = x[0];\n\n // Reduce with x^8 + x^4 + x^3 + x + 1 until order is less than 8\n r[7] = r14; // r[7] was 0\n r[6] ^= r14;\n r10 ^= r14;\n // Skip, because r13 is always 0\n r[4] ^= r12;\n r[5] = r12; // r[5] was 0\n r[7] ^= r12;\n r8 ^= r12;\n // Skip, because r11 is always 0\n r[2] ^= r10;\n r[3] = r10; // r[3] was 0\n r[5] ^= r10;\n r[6] ^= r10;\n r[1] = r14; // r[1] was 0\n r[2] ^= r14; // Substitute r9 by r14 because they will always be equal\n r[4] ^= r14;\n r[5] ^= r14;\n r[0] ^= r8;\n r[1] ^= r8;\n r[3] ^= r8;\n r[4] ^= r8;\n}\n\n/**\n * Invert x in GF(2^8) and write the result to r.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to invert (will be modified)\n */\nexport function gf256Inv(r: Uint32Array, x: Uint32Array): void {\n if (r.length !== 8 || x.length !== 8) {\n throw new Error(\"gf256Inv: arrays must have 8 elements\");\n }\n\n const y = new Uint32Array(8);\n const z = new Uint32Array(8);\n\n gf256Square(y, x); // y = x^2\n const y2 = new Uint32Array(y);\n gf256Square(y, y2); // y = x^4\n gf256Square(r, y); // r = x^8\n gf256Mul(z, r, x); // z = x^9\n const r2a = new Uint32Array(r);\n gf256Square(r, r2a); // r = x^16\n const r2b = new Uint32Array(r);\n gf256Mul(r, r2b, z); // r = x^25\n const r2c = new Uint32Array(r);\n gf256Square(r, r2c); // r = x^50\n gf256Square(z, r); // z = x^100\n const z2 = new Uint32Array(z);\n gf256Square(z, z2); // z = x^200\n const r2d = new Uint32Array(r);\n gf256Mul(r, r2d, z); // r = x^250\n const r2e = new Uint32Array(r);\n gf256Mul(r, r2e, y); // r = x^254\n}\n","// Ported from bc-shamir-rust/src/interpolate.rs\n\nimport { memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport { MAX_SECRET_LEN } from \"./index.js\";\nimport { bitslice, bitsliceSetall, gf256Add, gf256Inv, gf256Mul, unbitslice } from \"./hazmat.js\";\n\n/**\n * Calculate the lagrange basis coefficients for the lagrange polynomial\n * defined by the x coordinates xc at the value x.\n *\n * After the function runs, the values array should hold data satisfying:\n * --- (x-xc[j])\n * values[i] = | | -------------\n * j != i (xc[i]-xc[j])\n *\n * @param values - Output array for the lagrange basis values\n * @param n - Number of points (length of the xc array, 0 < n <= 32)\n * @param xc - Array of x components to use as interpolating points\n * @param x - x coordinate to evaluate lagrange polynomials at\n */\nfunction hazmatLagrangeBasis(values: Uint8Array, n: number, xc: Uint8Array, x: number): void {\n // call the contents of xc [ x0 x1 x2 ... xn-1 ]\n const xx = new Uint8Array(32 + 16);\n const xSlice = new Uint32Array(8);\n const lxi: Uint32Array[] = [];\n for (let i = 0; i < n; i++) {\n lxi.push(new Uint32Array(8));\n }\n const numerator = new Uint32Array(8);\n const denominator = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n xx.set(xc.subarray(0, n), 0);\n\n // xx now contains bitsliced [ x0 x1 x2 ... xn-1 0 0 0 ... ]\n for (let i = 0; i < n; i++) {\n // lxi = bitsliced [ xi xi+1 xi+2 ... xi-1 0 0 0 ]\n bitslice(lxi[i], xx.subarray(i));\n xx[i + n] = xx[i];\n }\n\n bitsliceSetall(xSlice, x);\n bitsliceSetall(numerator, 1);\n bitsliceSetall(denominator, 1);\n\n for (let i = 1; i < n; i++) {\n temp.set(xSlice);\n gf256Add(temp, lxi[i]);\n // temp = [ x-xi+i x-xi+2 x-xi+3 ... x-xi x x x]\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n temp.set(lxi[0]);\n gf256Add(temp, lxi[i]);\n // temp = [x0-xi+1 x1-xi+1 x2-xi+2 ... xn-x0 0 0 0]\n const denominator2 = new Uint32Array(denominator);\n gf256Mul(denominator, denominator2, temp);\n }\n\n // At this stage the numerator contains\n // [ num0 num1 num2 ... numn 0 0 0]\n //\n // where numi = prod(j, j!=i, x-xj )\n //\n // and the denominator contains\n // [ d0 d1 d2 ... dn 0 0 0]\n //\n // where di = prod(j, j!=i, xi-xj)\n\n gf256Inv(temp, denominator);\n\n // gf256_inv uses exponentiation to calculate inverse, so the zeros end up\n // remaining zeros.\n\n // tmp = [ 1/d0 1/d1 1/d2 ... 1/dn 0 0 0]\n\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n // numerator now contains [ l_n_0(x) l_n_1(x) ... l_n_n-1(x) 0 0 0]\n // use the xx array to unpack it\n\n unbitslice(xx, numerator);\n\n // copy results to output array\n values.set(xx.subarray(0, n), 0);\n}\n\n/**\n * Safely interpolate the polynomial going through\n * the points (x0 [y0_0 y0_1 y0_2 ... y0_31]) , (x1 [y1_0 ...]), ...\n *\n * where\n * xi points to [x0 x1 ... xn-1 ]\n * y contains an array of pointers to 32-bit arrays of y values\n * y contains [y0 y1 y2 ... yn-1]\n * and each of the yi arrays contain [yi_0 yi_i ... yi_31].\n *\n * @param n - Number of points to interpolate\n * @param xi - x coordinates for points (array of length n)\n * @param yl - Length of y coordinate arrays\n * @param yij - Array of n arrays of length yl\n * @param x - Coordinate to interpolate at\n * @returns The interpolated result of length yl\n */\nexport function interpolate(\n n: number,\n xi: Uint8Array,\n yl: number,\n yij: Uint8Array[],\n x: number,\n): Uint8Array {\n // The hazmat gf256 implementation needs the y-coordinate data\n // to be in 32-byte blocks\n const y: Uint8Array[] = [];\n for (let i = 0; i < n; i++) {\n y.push(new Uint8Array(MAX_SECRET_LEN));\n }\n const values = new Uint8Array(MAX_SECRET_LEN);\n\n for (let i = 0; i < n; i++) {\n y[i].set(yij[i].subarray(0, yl), 0);\n }\n\n const lagrange = new Uint8Array(n);\n const ySlice = new Uint32Array(8);\n const resultSlice = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n hazmatLagrangeBasis(lagrange, n, xi, x);\n\n bitsliceSetall(resultSlice, 0);\n\n for (let i = 0; i < n; i++) {\n bitslice(ySlice, y[i]);\n bitsliceSetall(temp, lagrange[i]);\n const temp2 = new Uint32Array(temp);\n gf256Mul(temp, temp2, ySlice);\n gf256Add(resultSlice, temp);\n }\n\n unbitslice(values, resultSlice);\n\n // the calling code is only expecting yl bytes back\n const result = new Uint8Array(yl);\n result.set(values.subarray(0, yl), 0);\n\n // clean up stack\n memzero(lagrange);\n memzero(ySlice);\n memzero(resultSlice);\n memzero(temp);\n memzeroVecVecU8(y);\n memzero(values);\n\n return result;\n}\n","// Ported from bc-shamir-rust/src/shamir.rs\n\nimport { hmacSha256, memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\n\nimport { ShamirError, ShamirErrorType } from \"./error.js\";\nimport { MAX_SECRET_LEN, MAX_SHARE_COUNT, MIN_SECRET_LEN } from \"./index.js\";\nimport { interpolate } from \"./interpolate.js\";\n\nconst SECRET_INDEX = 255;\nconst DIGEST_INDEX = 254;\n\nfunction createDigest(randomData: Uint8Array, sharedSecret: Uint8Array): Uint8Array {\n return hmacSha256(randomData, sharedSecret);\n}\n\nfunction validateParameters(threshold: number, shareCount: number, secretLength: number): void {\n if (shareCount > MAX_SHARE_COUNT) {\n throw new ShamirError(ShamirErrorType.TooManyShares);\n } else if (threshold < 1 || threshold > shareCount) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n } else if (secretLength > MAX_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooLong);\n } else if (secretLength < MIN_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooShort);\n } else if ((secretLength & 1) !== 0) {\n throw new ShamirError(ShamirErrorType.SecretNotEvenLen);\n }\n}\n\n/**\n * Splits a secret into shares using the Shamir secret sharing algorithm.\n *\n * @param threshold - The minimum number of shares required to reconstruct the\n * secret. Must be greater than or equal to 1 and less than or equal to\n * shareCount.\n * @param shareCount - The total number of shares to generate. Must be at least\n * threshold and less than or equal to MAX_SHARE_COUNT.\n * @param secret - A Uint8Array containing the secret to be split. Must be at\n * least MIN_SECRET_LEN bytes long and at most MAX_SECRET_LEN bytes long.\n * The length must be an even number.\n * @param randomGenerator - An implementation of the RandomNumberGenerator\n * interface, used to generate random data.\n * @returns An array of Uint8Array representing the shares of the secret.\n * @throws ShamirError if parameters are invalid\n *\n * @example\n * ```typescript\n * import { splitSecret } from \"@bcts/shamir\";\n * import { SecureRandomNumberGenerator } from \"@bcts/rand\";\n *\n * const threshold = 2;\n * const shareCount = 3;\n * const secret = new TextEncoder().encode(\"my secret belongs to me.\");\n * const rng = new SecureRandomNumberGenerator();\n *\n * const shares = splitSecret(threshold, shareCount, secret, rng);\n * console.log(shares.length); // 3\n * ```\n */\nexport function splitSecret(\n threshold: number,\n shareCount: number,\n secret: Uint8Array,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[] {\n validateParameters(threshold, shareCount, secret.length);\n\n if (threshold === 1) {\n // just return shareCount copies of the secret\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret));\n }\n return result;\n } else {\n const x = new Uint8Array(shareCount);\n const y: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n y.push(new Uint8Array(secret.length));\n }\n let n = 0;\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret.length));\n }\n\n for (let index = 0; index < threshold - 2; index++) {\n randomGenerator.fillRandomData(result[index]);\n x[n] = index;\n y[n].set(result[index]);\n n++;\n }\n\n // generate secret_length - 4 bytes worth of random data\n const digest = new Uint8Array(secret.length);\n randomGenerator.fillRandomData(digest.subarray(4));\n // put 4 bytes of digest at the top of the digest array\n const d = createDigest(digest.subarray(4), secret);\n digest.set(d.subarray(0, 4), 0);\n x[n] = DIGEST_INDEX;\n y[n].set(digest);\n n++;\n\n x[n] = SECRET_INDEX;\n y[n].set(secret);\n n++;\n\n for (let index = threshold - 2; index < shareCount; index++) {\n const v = interpolate(n, x, secret.length, y, index);\n result[index].set(v);\n }\n\n // clean up stack\n memzero(digest);\n memzero(x);\n memzeroVecVecU8(y);\n\n return result;\n }\n}\n\n/**\n * Recovers the secret from the given shares using the Shamir secret sharing\n * algorithm.\n *\n * @param indexes - An array of indexes of the shares to be used for recovering\n * the secret. These are the indexes of the shares returned by splitSecret.\n * @param shares - An array of shares of the secret matching the indexes in\n * indexes. These are the shares returned by splitSecret.\n * @returns A Uint8Array representing the recovered secret.\n * @throws ShamirError if parameters are invalid or checksum verification fails\n *\n * @example\n * ```typescript\n * import { recoverSecret } from \"@bcts/shamir\";\n *\n * const indexes = [0, 2];\n * const shares = [\n * new Uint8Array([47, 165, 102, 232, ...]),\n * new Uint8Array([221, 174, 116, 201, ...]),\n * ];\n *\n * const secret = recoverSecret(indexes, shares);\n * console.log(new TextDecoder().decode(secret)); // \"my secret belongs to me.\"\n * ```\n */\nexport function recoverSecret(indexes: number[], shares: Uint8Array[]): Uint8Array {\n const threshold = shares.length;\n if (threshold === 0 || indexes.length !== threshold) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n }\n\n const shareLength = shares[0].length;\n validateParameters(threshold, threshold, shareLength);\n\n const allSameLength = shares.every((share) => share.length === shareLength);\n if (!allSameLength) {\n throw new ShamirError(ShamirErrorType.SharesUnequalLength);\n }\n\n if (threshold === 1) {\n return new Uint8Array(shares[0]);\n } else {\n const indexesU8 = new Uint8Array(indexes);\n\n const digest = interpolate(threshold, indexesU8, shareLength, shares, DIGEST_INDEX);\n const secret = interpolate(threshold, indexesU8, shareLength, shares, SECRET_INDEX);\n const verify = createDigest(digest.subarray(4), secret);\n\n let valid = true;\n for (let i = 0; i < 4; i++) {\n valid = valid && digest[i] === verify[i];\n }\n\n memzero(digest);\n memzero(verify);\n\n if (!valid) {\n throw new ShamirError(ShamirErrorType.ChecksumFailure);\n }\n\n return secret;\n }\n}\n","// Blockchain Commons Shamir Secret Sharing\n// Ported from bc-shamir-rust\n//\n// This is a pure TypeScript implementation of Shamir's Secret Sharing (SSS),\n// a cryptographic technique in which a secret is divided into parts, called\n// shares, in such a way that a threshold of several shares are needed to\n// reconstruct the secret. The shares are distributed in a way that makes it\n// impossible for an attacker to know anything about the secret without having\n// a threshold of shares. If the number of shares is less than the threshold,\n// then no information about the secret is revealed.\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = 16;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = 32;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = 16;\n\n// Error types\nexport { ShamirError, ShamirErrorType, type ShamirResult } from \"./error.js\";\n\n// Main functions\nexport { splitSecret, recoverSecret } from \"./shamir.js\";\n\n// Low-level operations (hazmat)\nexport {\n bitslice,\n unbitslice,\n bitsliceSetall,\n gf256Add,\n gf256Mul,\n gf256Square,\n gf256Inv,\n} from \"./hazmat.js\";\n\n// Interpolation\nexport { interpolate } from \"./interpolate.js\";\n"],"mappings":"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AG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,G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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/error.ts","../src/hazmat.ts","../src/interpolate.ts","../src/shamir.ts","../src/index.ts"],"sourcesContent":["/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/error.rs\n\n/**\n * Error types for Shamir secret sharing operations.\n *\n * Each variant mirrors a corresponding `Error::*` enum in\n * `bc-shamir-rust/src/error.rs` with the same trigger conditions and the\n * same default `Display` strings.\n *\n * Note on `InterpolationFailure`: this variant is **reserved but\n * unreachable** in both the Rust and TypeScript implementations.\n * `interpolate()` in `interpolate.ts` never actually returns / throws an\n * interpolation failure today — the Lagrange-basis math always succeeds\n * for any well-formed input. The variant is kept for forward\n * compatibility (e.g. should a future revision add input validation that\n * could reject pathological cases) and to keep the TS error type a 1:1\n * mirror of Rust's `Error` enum.\n */\nexport enum ShamirErrorType {\n SecretTooLong = \"SecretTooLong\",\n TooManyShares = \"TooManyShares\",\n /**\n * Reserved / unreachable in both Rust and TS today. See enum doc above.\n */\n InterpolationFailure = \"InterpolationFailure\",\n ChecksumFailure = \"ChecksumFailure\",\n SecretTooShort = \"SecretTooShort\",\n SecretNotEvenLen = \"SecretNotEvenLen\",\n InvalidThreshold = \"InvalidThreshold\",\n SharesUnequalLength = \"SharesUnequalLength\",\n}\n\n/**\n * Error class for Shamir secret sharing operations.\n */\nexport class ShamirError extends Error {\n readonly type: ShamirErrorType;\n\n constructor(type: ShamirErrorType, message?: string) {\n super(message ?? ShamirError.defaultMessage(type));\n this.type = type;\n this.name = \"ShamirError\";\n }\n\n private static defaultMessage(type: ShamirErrorType): string {\n switch (type) {\n case ShamirErrorType.SecretTooLong:\n return \"secret is too long\";\n case ShamirErrorType.TooManyShares:\n return \"too many shares\";\n case ShamirErrorType.InterpolationFailure:\n return \"interpolation failed\";\n case ShamirErrorType.ChecksumFailure:\n return \"checksum failure\";\n case ShamirErrorType.SecretTooShort:\n return \"secret is too short\";\n case ShamirErrorType.SecretNotEvenLen:\n return \"secret is not of even length\";\n case ShamirErrorType.InvalidThreshold:\n return \"invalid threshold\";\n case ShamirErrorType.SharesUnequalLength:\n return \"shares have unequal length\";\n }\n }\n}\n\n/**\n * Mirrors Rust's `Result<T, Error>` for API parity.\n *\n * The TypeScript port surfaces failures by throwing `ShamirError`\n * instances rather than returning a sum type, so this alias is a no-op\n * (`ShamirResult<T>` ≡ `T`). It is kept so signatures published in\n * `@bcts/shamir` remain visually parallel to their Rust counterparts.\n */\nexport type ShamirResult<T> = T;\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/hazmat.rs\n// GF(2^8) bitsliced polynomial operations for Shamir secret sharing.\n//\n// **Defensive arity guards.** Each helper here checks its array-length\n// preconditions (`r.length === 8`, `x.length >= 32`, …) and throws a\n// plain `Error` on violation. These guards mirror Rust's slice-indexing\n// `panic!` semantics — they signal an internal *contract violation*\n// (programmer error), not an end-user input error, and are deliberately\n// **not** elevated to `ShamirError`: that type carries variants for\n// recoverable, user-facing failures of the public `splitSecret` /\n// `recoverSecret` APIs, and has no variant matching \"wrong array arity\".\n// The public Shamir API never triggers these guards in normal use.\n\nimport { memzero } from \"@bcts/crypto\";\n\n/**\n * Internal contract guard. Mirrors a Rust `assert!(condition, message)`\n * panic on the boundary between hazmat helpers — kept as a bare `Error`\n * so it cannot be confused with a `ShamirError` from the public API.\n */\nfunction assertContract(condition: boolean, message: string): void {\n if (!condition) {\n throw new Error(message);\n }\n}\n\n/**\n * Convert an array of bytes into a bitsliced representation.\n * Takes the first 32 bytes from x and produces 8 u32 values.\n *\n * @param r - Output array of 8 u32 values (bitsliced representation)\n * @param x - Input array of at least 32 bytes\n */\nexport function bitslice(r: Uint32Array, x: Uint8Array): void {\n assertContract(x.length >= 32, \"bitslice: input must be at least 32 bytes\");\n assertContract(r.length === 8, \"bitslice: output must have 8 elements\");\n\n memzero(r);\n\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n const cur = x[arrIdx];\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n // r[bitIdx] |= ((cur & (1 << bitIdx)) >> bitIdx) << arrIdx\n r[bitIdx] |= ((cur & (1 << bitIdx)) >>> bitIdx) << arrIdx;\n }\n }\n}\n\n/**\n * Convert a bitsliced representation back to bytes.\n *\n * @param r - Output array of at least 32 bytes\n * @param x - Input array of 8 u32 values (bitsliced representation)\n */\nexport function unbitslice(r: Uint8Array, x: Uint32Array): void {\n assertContract(r.length >= 32, \"unbitslice: output must be at least 32 bytes\");\n assertContract(x.length === 8, \"unbitslice: input must have 8 elements\");\n\n memzero(r.subarray(0, 32));\n\n for (let bitIdx = 0; bitIdx < 8; bitIdx++) {\n const cur = x[bitIdx];\n for (let arrIdx = 0; arrIdx < 32; arrIdx++) {\n // r[arrIdx] |= ((cur & (1 << arrIdx)) >> arrIdx) << bitIdx\n r[arrIdx] |= ((cur & (1 << arrIdx)) >>> arrIdx) << bitIdx;\n }\n }\n}\n\n/**\n * Set all 32 positions in a bitsliced array to the same byte value.\n *\n * @param r - Output array of 8 u32 values\n * @param x - Byte value to set in all positions\n */\nexport function bitsliceSetall(r: Uint32Array, x: number): void {\n assertContract(r.length === 8, \"bitsliceSetall: output must have 8 elements\");\n\n for (let idx = 0; idx < 8; idx++) {\n // JavaScript needs special handling for the arithmetic right shift\n // This mirrors: *r = (((((x as u32) & (1u32.wrapping_shl(idx as u32)))\n // .wrapping_shl(31 - idx as u32)) as i32)\n // .wrapping_shr(31)) as u32;\n const bit = (x >>> idx) & 1;\n r[idx] = bit === 1 ? 0xffffffff : 0;\n }\n}\n\n/**\n * Add (XOR) r with x and store the result in r.\n * In GF(2^8), addition is XOR.\n *\n * @param r - First operand and result\n * @param x - Second operand\n */\nexport function gf256Add(r: Uint32Array, x: Uint32Array): void {\n assertContract(r.length === 8 && x.length === 8, \"gf256Add: arrays must have 8 elements\");\n\n for (let i = 0; i < 8; i++) {\n r[i] ^= x[i];\n }\n}\n\n/**\n * Safely multiply two bitsliced polynomials in GF(2^8) reduced by\n * x^8 + x^4 + x^3 + x + 1. r and a may overlap, but overlapping of r\n * and b will produce an incorrect result! If you need to square a polynomial\n * use gf256Square instead.\n *\n * @param r - Result array (8 u32 values)\n * @param a - First operand (may overlap with r)\n * @param b - Second operand (must NOT overlap with r)\n */\nexport function gf256Mul(r: Uint32Array, a: Uint32Array, b: Uint32Array): void {\n assertContract(\n r.length === 8 && a.length === 8 && b.length === 8,\n \"gf256Mul: arrays must have 8 elements\",\n );\n\n // Russian Peasant multiplication on two bitsliced polynomials\n const a2 = new Uint32Array(a);\n\n r[0] = a2[0] & b[0];\n r[1] = a2[1] & b[0];\n r[2] = a2[2] & b[0];\n r[3] = a2[3] & b[0];\n r[4] = a2[4] & b[0];\n r[5] = a2[5] & b[0];\n r[6] = a2[6] & b[0];\n r[7] = a2[7] & b[0];\n a2[0] ^= a2[7]; // reduce\n a2[2] ^= a2[7];\n a2[3] ^= a2[7];\n\n r[0] ^= a2[7] & b[1]; // add\n r[1] ^= a2[0] & b[1];\n r[2] ^= a2[1] & b[1];\n r[3] ^= a2[2] & b[1];\n r[4] ^= a2[3] & b[1];\n r[5] ^= a2[4] & b[1];\n r[6] ^= a2[5] & b[1];\n r[7] ^= a2[6] & b[1];\n a2[7] ^= a2[6]; // reduce\n a2[1] ^= a2[6];\n a2[2] ^= a2[6];\n\n r[0] ^= a2[6] & b[2]; // add\n r[1] ^= a2[7] & b[2];\n r[2] ^= a2[0] & b[2];\n r[3] ^= a2[1] & b[2];\n r[4] ^= a2[2] & b[2];\n r[5] ^= a2[3] & b[2];\n r[6] ^= a2[4] & b[2];\n r[7] ^= a2[5] & b[2];\n a2[6] ^= a2[5]; // reduce\n a2[0] ^= a2[5];\n a2[1] ^= a2[5];\n\n r[0] ^= a2[5] & b[3]; // add\n r[1] ^= a2[6] & b[3];\n r[2] ^= a2[7] & b[3];\n r[3] ^= a2[0] & b[3];\n r[4] ^= a2[1] & b[3];\n r[5] ^= a2[2] & b[3];\n r[6] ^= a2[3] & b[3];\n r[7] ^= a2[4] & b[3];\n a2[5] ^= a2[4]; // reduce\n a2[7] ^= a2[4];\n a2[0] ^= a2[4];\n\n r[0] ^= a2[4] & b[4]; // add\n r[1] ^= a2[5] & b[4];\n r[2] ^= a2[6] & b[4];\n r[3] ^= a2[7] & b[4];\n r[4] ^= a2[0] & b[4];\n r[5] ^= a2[1] & b[4];\n r[6] ^= a2[2] & b[4];\n r[7] ^= a2[3] & b[4];\n a2[4] ^= a2[3]; // reduce\n a2[6] ^= a2[3];\n a2[7] ^= a2[3];\n\n r[0] ^= a2[3] & b[5]; // add\n r[1] ^= a2[4] & b[5];\n r[2] ^= a2[5] & b[5];\n r[3] ^= a2[6] & b[5];\n r[4] ^= a2[7] & b[5];\n r[5] ^= a2[0] & b[5];\n r[6] ^= a2[1] & b[5];\n r[7] ^= a2[2] & b[5];\n a2[3] ^= a2[2]; // reduce\n a2[5] ^= a2[2];\n a2[6] ^= a2[2];\n\n r[0] ^= a2[2] & b[6]; // add\n r[1] ^= a2[3] & b[6];\n r[2] ^= a2[4] & b[6];\n r[3] ^= a2[5] & b[6];\n r[4] ^= a2[6] & b[6];\n r[5] ^= a2[7] & b[6];\n r[6] ^= a2[0] & b[6];\n r[7] ^= a2[1] & b[6];\n a2[2] ^= a2[1]; // reduce\n a2[4] ^= a2[1];\n a2[5] ^= a2[1];\n\n r[0] ^= a2[1] & b[7]; // add\n r[1] ^= a2[2] & b[7];\n r[2] ^= a2[3] & b[7];\n r[3] ^= a2[4] & b[7];\n r[4] ^= a2[5] & b[7];\n r[5] ^= a2[6] & b[7];\n r[6] ^= a2[7] & b[7];\n r[7] ^= a2[0] & b[7];\n}\n\n/**\n * Square x in GF(2^8) and write the result to r.\n * r and x may overlap.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to square\n */\nexport function gf256Square(r: Uint32Array, x: Uint32Array): void {\n assertContract(r.length === 8 && x.length === 8, \"gf256Square: arrays must have 8 elements\");\n\n // Use the Freshman's Dream rule to square the polynomial\n // Assignments are done from 7 downto 0, because this allows\n // in-place operation (e.g. gf256Square(r, r))\n const r14 = x[7];\n const r12 = x[6];\n let r10 = x[5];\n let r8 = x[4];\n r[6] = x[3];\n r[4] = x[2];\n r[2] = x[1];\n r[0] = x[0];\n\n // Reduce with x^8 + x^4 + x^3 + x + 1 until order is less than 8\n r[7] = r14; // r[7] was 0\n r[6] ^= r14;\n r10 ^= r14;\n // Skip, because r13 is always 0\n r[4] ^= r12;\n r[5] = r12; // r[5] was 0\n r[7] ^= r12;\n r8 ^= r12;\n // Skip, because r11 is always 0\n r[2] ^= r10;\n r[3] = r10; // r[3] was 0\n r[5] ^= r10;\n r[6] ^= r10;\n r[1] = r14; // r[1] was 0\n r[2] ^= r14; // Substitute r9 by r14 because they will always be equal\n r[4] ^= r14;\n r[5] ^= r14;\n r[0] ^= r8;\n r[1] ^= r8;\n r[3] ^= r8;\n r[4] ^= r8;\n}\n\n/**\n * Invert x in GF(2^8) and write the result to r.\n *\n * @param r - Result array (8 u32 values)\n * @param x - Value to invert (will be modified)\n */\nexport function gf256Inv(r: Uint32Array, x: Uint32Array): void {\n assertContract(r.length === 8 && x.length === 8, \"gf256Inv: arrays must have 8 elements\");\n\n const y = new Uint32Array(8);\n const z = new Uint32Array(8);\n\n gf256Square(y, x); // y = x^2\n const y2 = new Uint32Array(y);\n gf256Square(y, y2); // y = x^4\n gf256Square(r, y); // r = x^8\n gf256Mul(z, r, x); // z = x^9\n const r2a = new Uint32Array(r);\n gf256Square(r, r2a); // r = x^16\n const r2b = new Uint32Array(r);\n gf256Mul(r, r2b, z); // r = x^25\n const r2c = new Uint32Array(r);\n gf256Square(r, r2c); // r = x^50\n gf256Square(z, r); // z = x^100\n const z2 = new Uint32Array(z);\n gf256Square(z, z2); // z = x^200\n const r2d = new Uint32Array(r);\n gf256Mul(r, r2d, z); // r = x^250\n const r2e = new Uint32Array(r);\n gf256Mul(r, r2e, y); // r = x^254\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/interpolate.rs\n\nimport { memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport { MAX_SECRET_LEN } from \"./index.js\";\nimport { bitslice, bitsliceSetall, gf256Add, gf256Inv, gf256Mul, unbitslice } from \"./hazmat.js\";\n\n/**\n * Calculate the lagrange basis coefficients for the lagrange polynomial\n * defined by the x coordinates xc at the value x.\n *\n * After the function runs, the values array should hold data satisfying:\n * --- (x-xc[j])\n * values[i] = | | -------------\n * j != i (xc[i]-xc[j])\n *\n * @param values - Output array for the lagrange basis values\n * @param n - Number of points (length of the xc array, 0 < n <= 32)\n * @param xc - Array of x components to use as interpolating points\n * @param x - x coordinate to evaluate lagrange polynomials at\n */\nfunction hazmatLagrangeBasis(values: Uint8Array, n: number, xc: Uint8Array, x: number): void {\n // call the contents of xc [ x0 x1 x2 ... xn-1 ]\n const xx = new Uint8Array(32 + 16);\n const xSlice = new Uint32Array(8);\n const lxi: Uint32Array[] = [];\n for (let i = 0; i < n; i++) {\n lxi.push(new Uint32Array(8));\n }\n const numerator = new Uint32Array(8);\n const denominator = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n xx.set(xc.subarray(0, n), 0);\n\n // xx now contains bitsliced [ x0 x1 x2 ... xn-1 0 0 0 ... ]\n for (let i = 0; i < n; i++) {\n // lxi = bitsliced [ xi xi+1 xi+2 ... xi-1 0 0 0 ]\n bitslice(lxi[i], xx.subarray(i));\n xx[i + n] = xx[i];\n }\n\n bitsliceSetall(xSlice, x);\n bitsliceSetall(numerator, 1);\n bitsliceSetall(denominator, 1);\n\n for (let i = 1; i < n; i++) {\n temp.set(xSlice);\n gf256Add(temp, lxi[i]);\n // temp = [ x-xi+i x-xi+2 x-xi+3 ... x-xi x x x]\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n temp.set(lxi[0]);\n gf256Add(temp, lxi[i]);\n // temp = [x0-xi+1 x1-xi+1 x2-xi+2 ... xn-x0 0 0 0]\n const denominator2 = new Uint32Array(denominator);\n gf256Mul(denominator, denominator2, temp);\n }\n\n // At this stage the numerator contains\n // [ num0 num1 num2 ... numn 0 0 0]\n //\n // where numi = prod(j, j!=i, x-xj )\n //\n // and the denominator contains\n // [ d0 d1 d2 ... dn 0 0 0]\n //\n // where di = prod(j, j!=i, xi-xj)\n\n gf256Inv(temp, denominator);\n\n // gf256_inv uses exponentiation to calculate inverse, so the zeros end up\n // remaining zeros.\n\n // tmp = [ 1/d0 1/d1 1/d2 ... 1/dn 0 0 0]\n\n const numerator2 = new Uint32Array(numerator);\n gf256Mul(numerator, numerator2, temp);\n\n // numerator now contains [ l_n_0(x) l_n_1(x) ... l_n_n-1(x) 0 0 0]\n // use the xx array to unpack it\n\n unbitslice(xx, numerator);\n\n // copy results to output array\n values.set(xx.subarray(0, n), 0);\n}\n\n/**\n * Safely interpolate the polynomial going through\n * the points (x0 [y0_0 y0_1 y0_2 ... y0_31]) , (x1 [y1_0 ...]), ...\n *\n * where\n * xi points to [x0 x1 ... xn-1 ]\n * y contains an array of pointers to 32-bit arrays of y values\n * y contains [y0 y1 y2 ... yn-1]\n * and each of the yi arrays contain [yi_0 yi_i ... yi_31].\n *\n * @param n - Number of points to interpolate\n * @param xi - x coordinates for points (array of length n)\n * @param yl - Length of y coordinate arrays\n * @param yij - Array of n arrays of length yl\n * @param x - Coordinate to interpolate at\n * @returns The interpolated result of length yl\n */\nexport function interpolate(\n n: number,\n xi: Uint8Array,\n yl: number,\n yij: Uint8Array[],\n x: number,\n): Uint8Array {\n // The hazmat gf256 implementation needs the y-coordinate data\n // to be in 32-byte blocks\n const y: Uint8Array[] = [];\n for (let i = 0; i < n; i++) {\n y.push(new Uint8Array(MAX_SECRET_LEN));\n }\n const values = new Uint8Array(MAX_SECRET_LEN);\n\n for (let i = 0; i < n; i++) {\n y[i].set(yij[i].subarray(0, yl), 0);\n }\n\n const lagrange = new Uint8Array(n);\n const ySlice = new Uint32Array(8);\n const resultSlice = new Uint32Array(8);\n const temp = new Uint32Array(8);\n\n hazmatLagrangeBasis(lagrange, n, xi, x);\n\n bitsliceSetall(resultSlice, 0);\n\n for (let i = 0; i < n; i++) {\n bitslice(ySlice, y[i]);\n bitsliceSetall(temp, lagrange[i]);\n const temp2 = new Uint32Array(temp);\n gf256Mul(temp, temp2, ySlice);\n gf256Add(resultSlice, temp);\n }\n\n unbitslice(values, resultSlice);\n\n // the calling code is only expecting yl bytes back\n const result = new Uint8Array(yl);\n result.set(values.subarray(0, yl), 0);\n\n // clean up stack\n memzero(lagrange);\n memzero(ySlice);\n memzero(resultSlice);\n memzero(temp);\n memzeroVecVecU8(y);\n memzero(values);\n\n return result;\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-shamir-rust/src/shamir.rs\n\nimport { hmacSha256, memzero, memzeroVecVecU8 } from \"@bcts/crypto\";\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\n\nimport { ShamirError, ShamirErrorType } from \"./error.js\";\nimport { MAX_SECRET_LEN, MAX_SHARE_COUNT, MIN_SECRET_LEN } from \"./index.js\";\nimport { interpolate } from \"./interpolate.js\";\n\nconst SECRET_INDEX = 255;\nconst DIGEST_INDEX = 254;\n\nfunction createDigest(randomData: Uint8Array, sharedSecret: Uint8Array): Uint8Array {\n return hmacSha256(randomData, sharedSecret);\n}\n\nfunction validateParameters(threshold: number, shareCount: number, secretLength: number): void {\n if (shareCount > MAX_SHARE_COUNT) {\n throw new ShamirError(ShamirErrorType.TooManyShares);\n } else if (threshold < 1 || threshold > shareCount) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n } else if (secretLength > MAX_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooLong);\n } else if (secretLength < MIN_SECRET_LEN) {\n throw new ShamirError(ShamirErrorType.SecretTooShort);\n } else if ((secretLength & 1) !== 0) {\n throw new ShamirError(ShamirErrorType.SecretNotEvenLen);\n }\n}\n\n/**\n * Splits a secret into shares using the Shamir secret sharing algorithm.\n *\n * @param threshold - The minimum number of shares required to reconstruct the\n * secret. Must be greater than or equal to 1 and less than or equal to\n * shareCount.\n * @param shareCount - The total number of shares to generate. Must be at least\n * threshold and less than or equal to MAX_SHARE_COUNT.\n * @param secret - A Uint8Array containing the secret to be split. Must be at\n * least MIN_SECRET_LEN bytes long and at most MAX_SECRET_LEN bytes long.\n * The length must be an even number.\n * @param randomGenerator - An implementation of the RandomNumberGenerator\n * interface, used to generate random data.\n * @returns An array of Uint8Array representing the shares of the secret.\n * @throws ShamirError if parameters are invalid\n *\n * @example\n * ```typescript\n * import { splitSecret } from \"@bcts/shamir\";\n * import { SecureRandomNumberGenerator } from \"@bcts/rand\";\n *\n * const threshold = 2;\n * const shareCount = 3;\n * const secret = new TextEncoder().encode(\"my secret belongs to me.\");\n * const rng = new SecureRandomNumberGenerator();\n *\n * const shares = splitSecret(threshold, shareCount, secret, rng);\n * console.log(shares.length); // 3\n * ```\n */\nexport function splitSecret(\n threshold: number,\n shareCount: number,\n secret: Uint8Array,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[] {\n validateParameters(threshold, shareCount, secret.length);\n\n if (threshold === 1) {\n // just return shareCount copies of the secret\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret));\n }\n return result;\n } else {\n const x = new Uint8Array(shareCount);\n const y: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n y.push(new Uint8Array(secret.length));\n }\n let n = 0;\n const result: Uint8Array[] = [];\n for (let i = 0; i < shareCount; i++) {\n result.push(new Uint8Array(secret.length));\n }\n\n for (let index = 0; index < threshold - 2; index++) {\n randomGenerator.fillRandomData(result[index]);\n x[n] = index;\n y[n].set(result[index]);\n n++;\n }\n\n // generate secret_length - 4 bytes worth of random data\n const digest = new Uint8Array(secret.length);\n randomGenerator.fillRandomData(digest.subarray(4));\n // put 4 bytes of digest at the top of the digest array\n const d = createDigest(digest.subarray(4), secret);\n digest.set(d.subarray(0, 4), 0);\n x[n] = DIGEST_INDEX;\n y[n].set(digest);\n n++;\n\n x[n] = SECRET_INDEX;\n y[n].set(secret);\n n++;\n\n for (let index = threshold - 2; index < shareCount; index++) {\n const v = interpolate(n, x, secret.length, y, index);\n result[index].set(v);\n }\n\n // clean up stack\n memzero(digest);\n memzero(x);\n memzeroVecVecU8(y);\n\n return result;\n }\n}\n\n/**\n * Recovers the secret from the given shares using the Shamir secret sharing\n * algorithm.\n *\n * @param indexes - An array of indexes of the shares to be used for recovering\n * the secret. These are the indexes of the shares returned by splitSecret.\n * @param shares - An array of shares of the secret matching the indexes in\n * indexes. These are the shares returned by splitSecret.\n * @returns A Uint8Array representing the recovered secret.\n * @throws ShamirError if parameters are invalid or checksum verification fails\n *\n * @example\n * ```typescript\n * import { recoverSecret } from \"@bcts/shamir\";\n *\n * const indexes = [0, 2];\n * const shares = [\n * new Uint8Array([47, 165, 102, 232, ...]),\n * new Uint8Array([221, 174, 116, 201, ...]),\n * ];\n *\n * const secret = recoverSecret(indexes, shares);\n * console.log(new TextDecoder().decode(secret)); // \"my secret belongs to me.\"\n * ```\n */\nexport function recoverSecret(indexes: number[], shares: Uint8Array[]): Uint8Array {\n const threshold = shares.length;\n if (threshold === 0 || indexes.length !== threshold) {\n throw new ShamirError(ShamirErrorType.InvalidThreshold);\n }\n\n const shareLength = shares[0].length;\n validateParameters(threshold, threshold, shareLength);\n\n const allSameLength = shares.every((share) => share.length === shareLength);\n if (!allSameLength) {\n throw new ShamirError(ShamirErrorType.SharesUnequalLength);\n }\n\n if (threshold === 1) {\n return new Uint8Array(shares[0]);\n } else {\n const indexesU8 = new Uint8Array(indexes);\n\n const digest = interpolate(threshold, indexesU8, shareLength, shares, DIGEST_INDEX);\n const secret = interpolate(threshold, indexesU8, shareLength, shares, SECRET_INDEX);\n const verify = createDigest(digest.subarray(4), secret);\n\n let valid = true;\n for (let i = 0; i < 4; i++) {\n valid = valid && digest[i] === verify[i];\n }\n\n memzero(digest);\n memzero(verify);\n\n if (!valid) {\n throw new ShamirError(ShamirErrorType.ChecksumFailure);\n }\n\n return secret;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Blockchain Commons Shamir Secret Sharing\n// Ported from bc-shamir-rust\n//\n// This is a pure TypeScript implementation of Shamir's Secret Sharing (SSS),\n// a cryptographic technique in which a secret is divided into parts, called\n// shares, in such a way that a threshold of several shares are needed to\n// reconstruct the secret. The shares are distributed in a way that makes it\n// impossible for an attacker to know anything about the secret without having\n// a threshold of shares. If the number of shares is less than the threshold,\n// then no information about the secret is revealed.\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = 16;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = 32;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = 16;\n\n// Error types\nexport { ShamirError, ShamirErrorType, type ShamirResult } from \"./error.js\";\n\n// Main functions\nexport { splitSecret, recoverSecret } from \"./shamir.js\";\n"],"mappings":"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,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AACZ,IAAG,MAAM,GAAG;AAEZ,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAAK,EAAE;AAClB,GAAE,MAAM,GAAG,KAA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"}
|