@bcts/sskr 1.0.0-alpha.20 → 1.0.0-alpha.21
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 +2 -1
- package/dist/index.cjs +15 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +20 -5
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +20 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +15 -0
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +15 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +10 -21
- package/src/encoding.ts +6 -0
- package/src/error.ts +6 -0
- package/src/index.ts +6 -0
- package/src/secret.ts +6 -0
- package/src/share.ts +6 -0
- package/src/spec.ts +6 -0
package/LICENSE
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
Copyright © 2023-2026 Blockchain Commons, LLC
|
|
2
|
-
Copyright © 2025-2026
|
|
2
|
+
Copyright © 2025-2026 Parity Technologies
|
|
3
|
+
|
|
3
4
|
|
|
4
5
|
Redistribution and use in source and binary forms, with or without modification,
|
|
5
6
|
are permitted provided that the following conditions are met:
|
package/dist/index.cjs
CHANGED
|
@@ -63,6 +63,11 @@ var SSKRError = class SSKRError extends Error {
|
|
|
63
63
|
//#endregion
|
|
64
64
|
//#region src/secret.ts
|
|
65
65
|
/**
|
|
66
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
67
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
/**
|
|
66
71
|
* A secret to be split into shares.
|
|
67
72
|
*/
|
|
68
73
|
var Secret = class Secret {
|
|
@@ -129,6 +134,11 @@ var Secret = class Secret {
|
|
|
129
134
|
//#endregion
|
|
130
135
|
//#region src/spec.ts
|
|
131
136
|
/**
|
|
137
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
138
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
139
|
+
*
|
|
140
|
+
*/
|
|
141
|
+
/**
|
|
132
142
|
* A specification for a group of shares within an SSKR split.
|
|
133
143
|
*/
|
|
134
144
|
var GroupSpec = class GroupSpec {
|
|
@@ -462,6 +472,11 @@ function combineShares(shares) {
|
|
|
462
472
|
//#endregion
|
|
463
473
|
//#region src/index.ts
|
|
464
474
|
/**
|
|
475
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
476
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
477
|
+
*
|
|
478
|
+
*/
|
|
479
|
+
/**
|
|
465
480
|
* The minimum length of a secret.
|
|
466
481
|
*/
|
|
467
482
|
const MIN_SECRET_LEN = _bcts_shamir.MIN_SECRET_LEN;
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["MAX_SHARE_COUNT","SecureRandomNumberGenerator","ShamirError","SHAMIR_MIN_SECRET_LEN","SHAMIR_MAX_SECRET_LEN","SHAMIR_MAX_SHARE_COUNT"],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/share.ts","../src/encoding.ts","../src/index.ts"],"sourcesContent":["// Ported from bc-sskr-rust/src/error.rs\n\nimport type { ShamirError } from \"@bcts/shamir\";\n\n/**\n * Error types for SSKR operations.\n */\nexport enum SSKRErrorType {\n DuplicateMemberIndex = \"DuplicateMemberIndex\",\n GroupSpecInvalid = \"GroupSpecInvalid\",\n GroupCountInvalid = \"GroupCountInvalid\",\n GroupThresholdInvalid = \"GroupThresholdInvalid\",\n MemberCountInvalid = \"MemberCountInvalid\",\n MemberThresholdInvalid = \"MemberThresholdInvalid\",\n NotEnoughGroups = \"NotEnoughGroups\",\n SecretLengthNotEven = \"SecretLengthNotEven\",\n SecretTooLong = \"SecretTooLong\",\n SecretTooShort = \"SecretTooShort\",\n ShareLengthInvalid = \"ShareLengthInvalid\",\n ShareReservedBitsInvalid = \"ShareReservedBitsInvalid\",\n SharesEmpty = \"SharesEmpty\",\n ShareSetInvalid = \"ShareSetInvalid\",\n ShamirError = \"ShamirError\",\n}\n\n/**\n * Error class for SSKR operations.\n */\nexport class SSKRError extends Error {\n readonly type: SSKRErrorType;\n readonly shamirError?: ShamirError | undefined;\n\n constructor(type: SSKRErrorType, message?: string, shamirError?: ShamirError) {\n super(message ?? SSKRError.defaultMessage(type, shamirError));\n this.type = type;\n this.shamirError = shamirError;\n this.name = \"SSKRError\";\n }\n\n private static defaultMessage(type: SSKRErrorType, shamirError?: ShamirError): string {\n switch (type) {\n case SSKRErrorType.DuplicateMemberIndex:\n return \"When combining shares, the provided shares contained a duplicate member index\";\n case SSKRErrorType.GroupSpecInvalid:\n return \"Invalid group specification.\";\n case SSKRErrorType.GroupCountInvalid:\n return \"When creating a split spec, the group count is invalid\";\n case SSKRErrorType.GroupThresholdInvalid:\n return \"SSKR group threshold is invalid\";\n case SSKRErrorType.MemberCountInvalid:\n return \"SSKR member count is invalid\";\n case SSKRErrorType.MemberThresholdInvalid:\n return \"SSKR member threshold is invalid\";\n case SSKRErrorType.NotEnoughGroups:\n return \"SSKR shares did not contain enough groups\";\n case SSKRErrorType.SecretLengthNotEven:\n return \"SSKR secret is not of even length\";\n case SSKRErrorType.SecretTooLong:\n return \"SSKR secret is too long\";\n case SSKRErrorType.SecretTooShort:\n return \"SSKR secret is too short\";\n case SSKRErrorType.ShareLengthInvalid:\n return \"SSKR shares did not contain enough serialized bytes\";\n case SSKRErrorType.ShareReservedBitsInvalid:\n return \"SSKR shares contained invalid reserved bits\";\n case SSKRErrorType.SharesEmpty:\n return \"SSKR shares were empty\";\n case SSKRErrorType.ShareSetInvalid:\n return \"SSKR shares were invalid\";\n case SSKRErrorType.ShamirError:\n return shamirError != null\n ? `SSKR Shamir error: ${shamirError.message}`\n : \"SSKR Shamir error\";\n }\n }\n\n static fromShamirError(error: ShamirError): SSKRError {\n return new SSKRError(SSKRErrorType.ShamirError, undefined, error);\n }\n}\n\nexport type SSKRResult<T> = T;\n","// Ported from bc-sskr-rust/src/secret.rs\n\nimport { MIN_SECRET_LEN, MAX_SECRET_LEN } from \"./index.js\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A secret to be split into shares.\n */\nexport class Secret {\n private readonly data: Uint8Array;\n\n private constructor(data: Uint8Array) {\n this.data = data;\n }\n\n /**\n * Creates a new Secret instance with the given data.\n *\n * @param data - The secret data to be split into shares.\n * @returns A new Secret instance.\n * @throws SSKRError if the length of the secret is less than\n * MIN_SECRET_LEN, greater than MAX_SECRET_LEN, or not even.\n */\n static new(data: Uint8Array | string): Secret {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const len = bytes.length;\n\n if (len < MIN_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooShort);\n }\n if (len > MAX_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooLong);\n }\n if ((len & 1) !== 0) {\n throw new SSKRError(SSKRErrorType.SecretLengthNotEven);\n }\n\n return new Secret(new Uint8Array(bytes));\n }\n\n /**\n * Returns the length of the secret.\n */\n len(): number {\n return this.data.length;\n }\n\n /**\n * Returns true if the secret is empty.\n */\n isEmpty(): boolean {\n return this.len() === 0;\n }\n\n /**\n * Returns a reference to the secret data.\n */\n getData(): Uint8Array {\n return this.data;\n }\n\n /**\n * Returns the secret data as a Uint8Array.\n */\n asRef(): Uint8Array {\n return this.data;\n }\n\n /**\n * Check equality with another Secret.\n */\n equals(other: Secret): boolean {\n if (this.data.length !== other.data.length) {\n return false;\n }\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i] !== other.data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Clone the secret.\n */\n clone(): Secret {\n return new Secret(new Uint8Array(this.data));\n }\n}\n","// Ported from bc-sskr-rust/src/spec.rs\n\nimport { MAX_SHARE_COUNT } from \"@bcts/shamir\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A specification for a group of shares within an SSKR split.\n */\nexport class GroupSpec {\n private readonly _memberThreshold: number;\n private readonly _memberCount: number;\n\n private constructor(memberThreshold: number, memberCount: number) {\n this._memberThreshold = memberThreshold;\n this._memberCount = memberCount;\n }\n\n /**\n * Creates a new GroupSpec instance with the given member threshold and count.\n *\n * @param memberThreshold - The minimum number of member shares required to\n * reconstruct the secret within the group.\n * @param memberCount - The total number of member shares in the group.\n * @returns A new GroupSpec instance.\n * @throws SSKRError if the member count is zero, if the member count is\n * greater than the maximum share count, or if the member threshold is\n * greater than the member count.\n */\n static new(memberThreshold: number, memberCount: number): GroupSpec {\n if (memberCount === 0) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberCount > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberThreshold > memberCount) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n return new GroupSpec(memberThreshold, memberCount);\n }\n\n /**\n * Returns the member share threshold for this group.\n */\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n /**\n * Returns the number of member shares in this group.\n */\n memberCount(): number {\n return this._memberCount;\n }\n\n /**\n * Parses a group specification from a string.\n * Format: \"M-of-N\" where M is the threshold and N is the count.\n */\n static parse(s: string): GroupSpec {\n const parts = s.split(\"-\");\n if (parts.length !== 3) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberThreshold = parseInt(parts[0], 10);\n if (isNaN(memberThreshold)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n if (parts[1] !== \"of\") {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberCount = parseInt(parts[2], 10);\n if (isNaN(memberCount)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n return GroupSpec.new(memberThreshold, memberCount);\n }\n\n /**\n * Creates a default GroupSpec (1-of-1).\n */\n static default(): GroupSpec {\n return GroupSpec.new(1, 1);\n }\n\n /**\n * Returns a string representation of the group spec.\n */\n toString(): string {\n return `${this._memberThreshold}-of-${this._memberCount}`;\n }\n}\n\n/**\n * A specification for an SSKR split.\n */\nexport class Spec {\n private readonly _groupThreshold: number;\n private readonly _groups: GroupSpec[];\n\n private constructor(groupThreshold: number, groups: GroupSpec[]) {\n this._groupThreshold = groupThreshold;\n this._groups = groups;\n }\n\n /**\n * Creates a new Spec instance with the given group threshold and groups.\n *\n * @param groupThreshold - The minimum number of groups required to\n * reconstruct the secret.\n * @param groups - The list of GroupSpec instances that define the groups\n * and their members.\n * @returns A new Spec instance.\n * @throws SSKRError if the group threshold is zero, if the group threshold\n * is greater than the number of groups, or if the number of groups is\n * greater than the maximum share count.\n */\n static new(groupThreshold: number, groups: GroupSpec[]): Spec {\n if (groupThreshold === 0) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groupThreshold > groups.length) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groups.length > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.GroupCountInvalid);\n }\n return new Spec(groupThreshold, groups);\n }\n\n /**\n * Returns the group threshold.\n */\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n /**\n * Returns a slice of the group specifications.\n */\n groups(): GroupSpec[] {\n return this._groups;\n }\n\n /**\n * Returns the number of groups.\n */\n groupCount(): number {\n return this._groups.length;\n }\n\n /**\n * Returns the total number of shares across all groups.\n */\n shareCount(): number {\n return this._groups.reduce((sum, g) => sum + g.memberCount(), 0);\n }\n}\n","// Ported from bc-sskr-rust/src/share.rs\n\nimport type { Secret } from \"./secret.js\";\n\n/**\n * A share in the SSKR scheme.\n */\nexport class SSKRShare {\n private readonly _identifier: number;\n private readonly _groupIndex: number;\n private readonly _groupThreshold: number;\n private readonly _groupCount: number;\n private readonly _memberIndex: number;\n private readonly _memberThreshold: number;\n private readonly _value: Secret;\n\n constructor(\n identifier: number,\n groupIndex: number,\n groupThreshold: number,\n groupCount: number,\n memberIndex: number,\n memberThreshold: number,\n value: Secret,\n ) {\n this._identifier = identifier;\n this._groupIndex = groupIndex;\n this._groupThreshold = groupThreshold;\n this._groupCount = groupCount;\n this._memberIndex = memberIndex;\n this._memberThreshold = memberThreshold;\n this._value = value;\n }\n\n identifier(): number {\n return this._identifier;\n }\n\n groupIndex(): number {\n return this._groupIndex;\n }\n\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n groupCount(): number {\n return this._groupCount;\n }\n\n memberIndex(): number {\n return this._memberIndex;\n }\n\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n value(): Secret {\n return this._value;\n }\n}\n","// Ported from bc-sskr-rust/src/encoding.rs\n\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\nimport { SecureRandomNumberGenerator } from \"@bcts/rand\";\nimport { splitSecret, recoverSecret, ShamirError } from \"@bcts/shamir\";\n\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\nimport { Secret } from \"./secret.js\";\nimport type { Spec } from \"./spec.js\";\nimport { SSKRShare } from \"./share.js\";\nimport { METADATA_SIZE_BYTES } from \"./index.js\";\n\n/**\n * Generates SSKR shares for the given Spec and Secret.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerate(spec: Spec, masterSecret: Secret): Uint8Array[][] {\n const rng = new SecureRandomNumberGenerator();\n return sskrGenerateUsing(spec, masterSecret, rng);\n}\n\n/**\n * Generates SSKR shares for the given Spec and Secret using the provided\n * random number generator.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @param randomGenerator - The random number generator to use for generating\n * shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerateUsing(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[][] {\n const groupsShares = generateShares(spec, masterSecret, randomGenerator);\n\n const result: Uint8Array[][] = groupsShares.map((group) => group.map(serializeShare));\n\n return result;\n}\n\n/**\n * Combines the given SSKR shares into a Secret.\n *\n * @param shares - A array of SSKR shares to be combined.\n * @returns The reconstructed Secret.\n * @throws SSKRError if the shares do not meet the necessary quorum of groups\n * and member shares within each group.\n */\nexport function sskrCombine(shares: Uint8Array[]): Secret {\n const sskrShares: SSKRShare[] = [];\n\n for (const share of shares) {\n const sskrShare = deserializeShare(share);\n sskrShares.push(sskrShare);\n }\n\n return combineShares(sskrShares);\n}\n\nfunction serializeShare(share: SSKRShare): Uint8Array {\n // pack the id, group and member data into 5 bytes:\n // 76543210 76543210 76543210\n // 76543210 76543210\n // ----------------====----====----====----\n // identifier: 16\n // group-threshold: 4\n // group-count: 4\n // group-index: 4\n // member-threshold: 4\n // reserved (MUST be zero): 4\n // member-index: 4\n\n const valueData = share.value().getData();\n const result = new Uint8Array(valueData.length + METADATA_SIZE_BYTES);\n\n const id = share.identifier();\n const gt = (share.groupThreshold() - 1) & 0xf;\n const gc = (share.groupCount() - 1) & 0xf;\n const gi = share.groupIndex() & 0xf;\n const mt = (share.memberThreshold() - 1) & 0xf;\n const mi = share.memberIndex() & 0xf;\n\n const id1 = id >> 8;\n const id2 = id & 0xff;\n\n result[0] = id1;\n result[1] = id2;\n result[2] = (gt << 4) | gc;\n result[3] = (gi << 4) | mt;\n result[4] = mi;\n result.set(valueData, METADATA_SIZE_BYTES);\n\n return result;\n}\n\nfunction deserializeShare(source: Uint8Array): SSKRShare {\n if (source.length < METADATA_SIZE_BYTES) {\n throw new SSKRError(SSKRErrorType.ShareLengthInvalid);\n }\n\n const groupThreshold = (source[2] >> 4) + 1;\n const groupCount = (source[2] & 0xf) + 1;\n\n if (groupThreshold > groupCount) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n\n const identifier = (source[0] << 8) | source[1];\n const groupIndex = source[3] >> 4;\n const memberThreshold = (source[3] & 0xf) + 1;\n const reserved = source[4] >> 4;\n if (reserved !== 0) {\n throw new SSKRError(SSKRErrorType.ShareReservedBitsInvalid);\n }\n const memberIndex = source[4] & 0xf;\n const value = Secret.new(source.subarray(METADATA_SIZE_BYTES));\n\n return new SSKRShare(\n identifier,\n groupIndex,\n groupThreshold,\n groupCount,\n memberIndex,\n memberThreshold,\n value,\n );\n}\n\nfunction generateShares(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): SSKRShare[][] {\n // assign a random identifier\n const identifierBytes = new Uint8Array(2);\n randomGenerator.fillRandomData(identifierBytes);\n const identifier = (identifierBytes[0] << 8) | identifierBytes[1];\n\n const groupsShares: SSKRShare[][] = [];\n\n let groupSecrets: Uint8Array[];\n try {\n groupSecrets = splitSecret(\n spec.groupThreshold(),\n spec.groupCount(),\n masterSecret.getData(),\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n for (let groupIndex = 0; groupIndex < spec.groups().length; groupIndex++) {\n const group = spec.groups()[groupIndex];\n const groupSecret = groupSecrets[groupIndex];\n\n let memberSecrets: Uint8Array[];\n try {\n memberSecrets = splitSecret(\n group.memberThreshold(),\n group.memberCount(),\n groupSecret,\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n const memberSSKRShares: SSKRShare[] = memberSecrets.map((memberSecret, memberIndex) => {\n const secret = Secret.new(memberSecret);\n return new SSKRShare(\n identifier,\n groupIndex,\n spec.groupThreshold(),\n spec.groupCount(),\n memberIndex,\n group.memberThreshold(),\n secret,\n );\n });\n\n groupsShares.push(memberSSKRShares);\n }\n\n return groupsShares;\n}\n\ninterface Group {\n groupIndex: number;\n memberThreshold: number;\n memberIndexes: number[];\n memberShares: Secret[];\n}\n\nfunction combineShares(shares: SSKRShare[]): Secret {\n let identifier = 0;\n let groupThreshold = 0;\n let groupCount = 0;\n\n if (shares.length === 0) {\n throw new SSKRError(SSKRErrorType.SharesEmpty);\n }\n\n let nextGroup = 0;\n const groups: Group[] = [];\n let secretLen = 0;\n\n for (let i = 0; i < shares.length; i++) {\n const share = shares[i];\n\n if (i === 0) {\n // on the first one, establish expected values for common metadata\n identifier = share.identifier();\n groupCount = share.groupCount();\n groupThreshold = share.groupThreshold();\n secretLen = share.value().len();\n } else {\n // on subsequent shares, check that common metadata matches\n if (\n share.identifier() !== identifier ||\n share.groupThreshold() !== groupThreshold ||\n share.groupCount() !== groupCount ||\n share.value().len() !== secretLen\n ) {\n throw new SSKRError(SSKRErrorType.ShareSetInvalid);\n }\n }\n\n // sort shares into member groups\n let groupFound = false;\n for (const group of groups) {\n if (share.groupIndex() === group.groupIndex) {\n groupFound = true;\n if (share.memberThreshold() !== group.memberThreshold) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n for (const memberIndex of group.memberIndexes) {\n if (share.memberIndex() === memberIndex) {\n throw new SSKRError(SSKRErrorType.DuplicateMemberIndex);\n }\n }\n if (group.memberIndexes.length < group.memberThreshold) {\n group.memberIndexes.push(share.memberIndex());\n group.memberShares.push(share.value().clone());\n }\n }\n }\n\n if (!groupFound) {\n const g: Group = {\n groupIndex: share.groupIndex(),\n memberThreshold: share.memberThreshold(),\n memberIndexes: [share.memberIndex()],\n memberShares: [share.value().clone()],\n };\n groups.push(g);\n nextGroup++;\n }\n }\n\n // Check that we have enough groups to recover the master secret\n if (nextGroup < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Here, all of the shares are unpacked into member groups. Now we go\n // through each group and recover the group secret, and then use the\n // result to recover the master secret\n const masterIndexes: number[] = [];\n const masterShares: Uint8Array[] = [];\n\n for (const group of groups) {\n // Only attempt to recover the group secret if we have enough shares\n if (group.memberIndexes.length < group.memberThreshold) {\n continue;\n }\n\n // Recover the group secret\n try {\n const memberSharesData = group.memberShares.map((s) => s.getData());\n const groupSecret = recoverSecret(group.memberIndexes, memberSharesData);\n masterIndexes.push(group.groupIndex);\n masterShares.push(groupSecret);\n } catch {\n // If we can't recover this group, just skip it\n continue;\n }\n\n // Stop if we have enough groups to recover the master secret\n if (masterIndexes.length === groupThreshold) {\n break;\n }\n }\n\n // If we don't have enough groups to recover the master secret, return an error\n if (masterIndexes.length < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Recover the master secret\n let masterSecretData: Uint8Array;\n try {\n masterSecretData = recoverSecret(masterIndexes, masterShares);\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n return Secret.new(masterSecretData);\n}\n","// Blockchain Commons Sharded Secret Key Reconstruction (SSKR)\n// Ported from bc-sskr-rust\n//\n// Sharded Secret Key Reconstruction (SSKR) is a protocol for splitting a\n// secret into a set of shares across one or more groups, such that the\n// secret can be reconstructed from any combination of shares totaling or\n// exceeding a threshold number of shares within each group and across all\n// groups. SSKR is a generalization of Shamir's Secret Sharing (SSS) that\n// allows for multiple groups and multiple thresholds.\n\nimport {\n MIN_SECRET_LEN as SHAMIR_MIN_SECRET_LEN,\n MAX_SECRET_LEN as SHAMIR_MAX_SECRET_LEN,\n MAX_SHARE_COUNT as SHAMIR_MAX_SHARE_COUNT,\n} from \"@bcts/shamir\";\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = SHAMIR_MIN_SECRET_LEN;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = SHAMIR_MAX_SECRET_LEN;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = SHAMIR_MAX_SHARE_COUNT;\n\n/**\n * The maximum number of groups in a split.\n */\nexport const MAX_GROUPS_COUNT = MAX_SHARE_COUNT;\n\n/**\n * The number of bytes used to encode the metadata for a share.\n */\nexport const METADATA_SIZE_BYTES = 5;\n\n/**\n * The minimum number of bytes required to encode a share.\n */\nexport const MIN_SERIALIZE_SIZE_BYTES = METADATA_SIZE_BYTES + MIN_SECRET_LEN;\n\n// Error types\nexport { SSKRError, SSKRErrorType, type SSKRResult } from \"./error.js\";\n\n// Secret\nexport { Secret } from \"./secret.js\";\n\n// Specifications\nexport { GroupSpec, Spec } from \"./spec.js\";\n\n// Encoding/Decoding\nexport { sskrGenerate, sskrGenerateUsing, sskrCombine } from \"./encoding.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["MAX_SHARE_COUNT","SecureRandomNumberGenerator","ShamirError","SHAMIR_MIN_SECRET_LEN","SHAMIR_MAX_SECRET_LEN","SHAMIR_MAX_SHARE_COUNT"],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/share.ts","../src/encoding.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-sskr-rust/src/error.rs\n\nimport type { ShamirError } from \"@bcts/shamir\";\n\n/**\n * Error types for SSKR operations.\n */\nexport enum SSKRErrorType {\n DuplicateMemberIndex = \"DuplicateMemberIndex\",\n GroupSpecInvalid = \"GroupSpecInvalid\",\n GroupCountInvalid = \"GroupCountInvalid\",\n GroupThresholdInvalid = \"GroupThresholdInvalid\",\n MemberCountInvalid = \"MemberCountInvalid\",\n MemberThresholdInvalid = \"MemberThresholdInvalid\",\n NotEnoughGroups = \"NotEnoughGroups\",\n SecretLengthNotEven = \"SecretLengthNotEven\",\n SecretTooLong = \"SecretTooLong\",\n SecretTooShort = \"SecretTooShort\",\n ShareLengthInvalid = \"ShareLengthInvalid\",\n ShareReservedBitsInvalid = \"ShareReservedBitsInvalid\",\n SharesEmpty = \"SharesEmpty\",\n ShareSetInvalid = \"ShareSetInvalid\",\n ShamirError = \"ShamirError\",\n}\n\n/**\n * Error class for SSKR operations.\n */\nexport class SSKRError extends Error {\n readonly type: SSKRErrorType;\n readonly shamirError?: ShamirError | undefined;\n\n constructor(type: SSKRErrorType, message?: string, shamirError?: ShamirError) {\n super(message ?? SSKRError.defaultMessage(type, shamirError));\n this.type = type;\n this.shamirError = shamirError;\n this.name = \"SSKRError\";\n }\n\n private static defaultMessage(type: SSKRErrorType, shamirError?: ShamirError): string {\n switch (type) {\n case SSKRErrorType.DuplicateMemberIndex:\n return \"When combining shares, the provided shares contained a duplicate member index\";\n case SSKRErrorType.GroupSpecInvalid:\n return \"Invalid group specification.\";\n case SSKRErrorType.GroupCountInvalid:\n return \"When creating a split spec, the group count is invalid\";\n case SSKRErrorType.GroupThresholdInvalid:\n return \"SSKR group threshold is invalid\";\n case SSKRErrorType.MemberCountInvalid:\n return \"SSKR member count is invalid\";\n case SSKRErrorType.MemberThresholdInvalid:\n return \"SSKR member threshold is invalid\";\n case SSKRErrorType.NotEnoughGroups:\n return \"SSKR shares did not contain enough groups\";\n case SSKRErrorType.SecretLengthNotEven:\n return \"SSKR secret is not of even length\";\n case SSKRErrorType.SecretTooLong:\n return \"SSKR secret is too long\";\n case SSKRErrorType.SecretTooShort:\n return \"SSKR secret is too short\";\n case SSKRErrorType.ShareLengthInvalid:\n return \"SSKR shares did not contain enough serialized bytes\";\n case SSKRErrorType.ShareReservedBitsInvalid:\n return \"SSKR shares contained invalid reserved bits\";\n case SSKRErrorType.SharesEmpty:\n return \"SSKR shares were empty\";\n case SSKRErrorType.ShareSetInvalid:\n return \"SSKR shares were invalid\";\n case SSKRErrorType.ShamirError:\n return shamirError != null\n ? `SSKR Shamir error: ${shamirError.message}`\n : \"SSKR Shamir error\";\n }\n }\n\n static fromShamirError(error: ShamirError): SSKRError {\n return new SSKRError(SSKRErrorType.ShamirError, undefined, error);\n }\n}\n\nexport type SSKRResult<T> = T;\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/secret.rs\n\nimport { MIN_SECRET_LEN, MAX_SECRET_LEN } from \"./index.js\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A secret to be split into shares.\n */\nexport class Secret {\n private readonly data: Uint8Array;\n\n private constructor(data: Uint8Array) {\n this.data = data;\n }\n\n /**\n * Creates a new Secret instance with the given data.\n *\n * @param data - The secret data to be split into shares.\n * @returns A new Secret instance.\n * @throws SSKRError if the length of the secret is less than\n * MIN_SECRET_LEN, greater than MAX_SECRET_LEN, or not even.\n */\n static new(data: Uint8Array | string): Secret {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const len = bytes.length;\n\n if (len < MIN_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooShort);\n }\n if (len > MAX_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooLong);\n }\n if ((len & 1) !== 0) {\n throw new SSKRError(SSKRErrorType.SecretLengthNotEven);\n }\n\n return new Secret(new Uint8Array(bytes));\n }\n\n /**\n * Returns the length of the secret.\n */\n len(): number {\n return this.data.length;\n }\n\n /**\n * Returns true if the secret is empty.\n */\n isEmpty(): boolean {\n return this.len() === 0;\n }\n\n /**\n * Returns a reference to the secret data.\n */\n getData(): Uint8Array {\n return this.data;\n }\n\n /**\n * Returns the secret data as a Uint8Array.\n */\n asRef(): Uint8Array {\n return this.data;\n }\n\n /**\n * Check equality with another Secret.\n */\n equals(other: Secret): boolean {\n if (this.data.length !== other.data.length) {\n return false;\n }\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i] !== other.data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Clone the secret.\n */\n clone(): Secret {\n return new Secret(new Uint8Array(this.data));\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/spec.rs\n\nimport { MAX_SHARE_COUNT } from \"@bcts/shamir\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A specification for a group of shares within an SSKR split.\n */\nexport class GroupSpec {\n private readonly _memberThreshold: number;\n private readonly _memberCount: number;\n\n private constructor(memberThreshold: number, memberCount: number) {\n this._memberThreshold = memberThreshold;\n this._memberCount = memberCount;\n }\n\n /**\n * Creates a new GroupSpec instance with the given member threshold and count.\n *\n * @param memberThreshold - The minimum number of member shares required to\n * reconstruct the secret within the group.\n * @param memberCount - The total number of member shares in the group.\n * @returns A new GroupSpec instance.\n * @throws SSKRError if the member count is zero, if the member count is\n * greater than the maximum share count, or if the member threshold is\n * greater than the member count.\n */\n static new(memberThreshold: number, memberCount: number): GroupSpec {\n if (memberCount === 0) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberCount > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberThreshold > memberCount) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n return new GroupSpec(memberThreshold, memberCount);\n }\n\n /**\n * Returns the member share threshold for this group.\n */\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n /**\n * Returns the number of member shares in this group.\n */\n memberCount(): number {\n return this._memberCount;\n }\n\n /**\n * Parses a group specification from a string.\n * Format: \"M-of-N\" where M is the threshold and N is the count.\n */\n static parse(s: string): GroupSpec {\n const parts = s.split(\"-\");\n if (parts.length !== 3) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberThreshold = parseInt(parts[0], 10);\n if (isNaN(memberThreshold)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n if (parts[1] !== \"of\") {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberCount = parseInt(parts[2], 10);\n if (isNaN(memberCount)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n return GroupSpec.new(memberThreshold, memberCount);\n }\n\n /**\n * Creates a default GroupSpec (1-of-1).\n */\n static default(): GroupSpec {\n return GroupSpec.new(1, 1);\n }\n\n /**\n * Returns a string representation of the group spec.\n */\n toString(): string {\n return `${this._memberThreshold}-of-${this._memberCount}`;\n }\n}\n\n/**\n * A specification for an SSKR split.\n */\nexport class Spec {\n private readonly _groupThreshold: number;\n private readonly _groups: GroupSpec[];\n\n private constructor(groupThreshold: number, groups: GroupSpec[]) {\n this._groupThreshold = groupThreshold;\n this._groups = groups;\n }\n\n /**\n * Creates a new Spec instance with the given group threshold and groups.\n *\n * @param groupThreshold - The minimum number of groups required to\n * reconstruct the secret.\n * @param groups - The list of GroupSpec instances that define the groups\n * and their members.\n * @returns A new Spec instance.\n * @throws SSKRError if the group threshold is zero, if the group threshold\n * is greater than the number of groups, or if the number of groups is\n * greater than the maximum share count.\n */\n static new(groupThreshold: number, groups: GroupSpec[]): Spec {\n if (groupThreshold === 0) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groupThreshold > groups.length) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groups.length > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.GroupCountInvalid);\n }\n return new Spec(groupThreshold, groups);\n }\n\n /**\n * Returns the group threshold.\n */\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n /**\n * Returns a slice of the group specifications.\n */\n groups(): GroupSpec[] {\n return this._groups;\n }\n\n /**\n * Returns the number of groups.\n */\n groupCount(): number {\n return this._groups.length;\n }\n\n /**\n * Returns the total number of shares across all groups.\n */\n shareCount(): number {\n return this._groups.reduce((sum, g) => sum + g.memberCount(), 0);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/share.rs\n\nimport type { Secret } from \"./secret.js\";\n\n/**\n * A share in the SSKR scheme.\n */\nexport class SSKRShare {\n private readonly _identifier: number;\n private readonly _groupIndex: number;\n private readonly _groupThreshold: number;\n private readonly _groupCount: number;\n private readonly _memberIndex: number;\n private readonly _memberThreshold: number;\n private readonly _value: Secret;\n\n constructor(\n identifier: number,\n groupIndex: number,\n groupThreshold: number,\n groupCount: number,\n memberIndex: number,\n memberThreshold: number,\n value: Secret,\n ) {\n this._identifier = identifier;\n this._groupIndex = groupIndex;\n this._groupThreshold = groupThreshold;\n this._groupCount = groupCount;\n this._memberIndex = memberIndex;\n this._memberThreshold = memberThreshold;\n this._value = value;\n }\n\n identifier(): number {\n return this._identifier;\n }\n\n groupIndex(): number {\n return this._groupIndex;\n }\n\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n groupCount(): number {\n return this._groupCount;\n }\n\n memberIndex(): number {\n return this._memberIndex;\n }\n\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n value(): Secret {\n return this._value;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/encoding.rs\n\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\nimport { SecureRandomNumberGenerator } from \"@bcts/rand\";\nimport { splitSecret, recoverSecret, ShamirError } from \"@bcts/shamir\";\n\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\nimport { Secret } from \"./secret.js\";\nimport type { Spec } from \"./spec.js\";\nimport { SSKRShare } from \"./share.js\";\nimport { METADATA_SIZE_BYTES } from \"./index.js\";\n\n/**\n * Generates SSKR shares for the given Spec and Secret.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerate(spec: Spec, masterSecret: Secret): Uint8Array[][] {\n const rng = new SecureRandomNumberGenerator();\n return sskrGenerateUsing(spec, masterSecret, rng);\n}\n\n/**\n * Generates SSKR shares for the given Spec and Secret using the provided\n * random number generator.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @param randomGenerator - The random number generator to use for generating\n * shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerateUsing(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[][] {\n const groupsShares = generateShares(spec, masterSecret, randomGenerator);\n\n const result: Uint8Array[][] = groupsShares.map((group) => group.map(serializeShare));\n\n return result;\n}\n\n/**\n * Combines the given SSKR shares into a Secret.\n *\n * @param shares - A array of SSKR shares to be combined.\n * @returns The reconstructed Secret.\n * @throws SSKRError if the shares do not meet the necessary quorum of groups\n * and member shares within each group.\n */\nexport function sskrCombine(shares: Uint8Array[]): Secret {\n const sskrShares: SSKRShare[] = [];\n\n for (const share of shares) {\n const sskrShare = deserializeShare(share);\n sskrShares.push(sskrShare);\n }\n\n return combineShares(sskrShares);\n}\n\nfunction serializeShare(share: SSKRShare): Uint8Array {\n // pack the id, group and member data into 5 bytes:\n // 76543210 76543210 76543210\n // 76543210 76543210\n // ----------------====----====----====----\n // identifier: 16\n // group-threshold: 4\n // group-count: 4\n // group-index: 4\n // member-threshold: 4\n // reserved (MUST be zero): 4\n // member-index: 4\n\n const valueData = share.value().getData();\n const result = new Uint8Array(valueData.length + METADATA_SIZE_BYTES);\n\n const id = share.identifier();\n const gt = (share.groupThreshold() - 1) & 0xf;\n const gc = (share.groupCount() - 1) & 0xf;\n const gi = share.groupIndex() & 0xf;\n const mt = (share.memberThreshold() - 1) & 0xf;\n const mi = share.memberIndex() & 0xf;\n\n const id1 = id >> 8;\n const id2 = id & 0xff;\n\n result[0] = id1;\n result[1] = id2;\n result[2] = (gt << 4) | gc;\n result[3] = (gi << 4) | mt;\n result[4] = mi;\n result.set(valueData, METADATA_SIZE_BYTES);\n\n return result;\n}\n\nfunction deserializeShare(source: Uint8Array): SSKRShare {\n if (source.length < METADATA_SIZE_BYTES) {\n throw new SSKRError(SSKRErrorType.ShareLengthInvalid);\n }\n\n const groupThreshold = (source[2] >> 4) + 1;\n const groupCount = (source[2] & 0xf) + 1;\n\n if (groupThreshold > groupCount) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n\n const identifier = (source[0] << 8) | source[1];\n const groupIndex = source[3] >> 4;\n const memberThreshold = (source[3] & 0xf) + 1;\n const reserved = source[4] >> 4;\n if (reserved !== 0) {\n throw new SSKRError(SSKRErrorType.ShareReservedBitsInvalid);\n }\n const memberIndex = source[4] & 0xf;\n const value = Secret.new(source.subarray(METADATA_SIZE_BYTES));\n\n return new SSKRShare(\n identifier,\n groupIndex,\n groupThreshold,\n groupCount,\n memberIndex,\n memberThreshold,\n value,\n );\n}\n\nfunction generateShares(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): SSKRShare[][] {\n // assign a random identifier\n const identifierBytes = new Uint8Array(2);\n randomGenerator.fillRandomData(identifierBytes);\n const identifier = (identifierBytes[0] << 8) | identifierBytes[1];\n\n const groupsShares: SSKRShare[][] = [];\n\n let groupSecrets: Uint8Array[];\n try {\n groupSecrets = splitSecret(\n spec.groupThreshold(),\n spec.groupCount(),\n masterSecret.getData(),\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n for (let groupIndex = 0; groupIndex < spec.groups().length; groupIndex++) {\n const group = spec.groups()[groupIndex];\n const groupSecret = groupSecrets[groupIndex];\n\n let memberSecrets: Uint8Array[];\n try {\n memberSecrets = splitSecret(\n group.memberThreshold(),\n group.memberCount(),\n groupSecret,\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n const memberSSKRShares: SSKRShare[] = memberSecrets.map((memberSecret, memberIndex) => {\n const secret = Secret.new(memberSecret);\n return new SSKRShare(\n identifier,\n groupIndex,\n spec.groupThreshold(),\n spec.groupCount(),\n memberIndex,\n group.memberThreshold(),\n secret,\n );\n });\n\n groupsShares.push(memberSSKRShares);\n }\n\n return groupsShares;\n}\n\ninterface Group {\n groupIndex: number;\n memberThreshold: number;\n memberIndexes: number[];\n memberShares: Secret[];\n}\n\nfunction combineShares(shares: SSKRShare[]): Secret {\n let identifier = 0;\n let groupThreshold = 0;\n let groupCount = 0;\n\n if (shares.length === 0) {\n throw new SSKRError(SSKRErrorType.SharesEmpty);\n }\n\n let nextGroup = 0;\n const groups: Group[] = [];\n let secretLen = 0;\n\n for (let i = 0; i < shares.length; i++) {\n const share = shares[i];\n\n if (i === 0) {\n // on the first one, establish expected values for common metadata\n identifier = share.identifier();\n groupCount = share.groupCount();\n groupThreshold = share.groupThreshold();\n secretLen = share.value().len();\n } else {\n // on subsequent shares, check that common metadata matches\n if (\n share.identifier() !== identifier ||\n share.groupThreshold() !== groupThreshold ||\n share.groupCount() !== groupCount ||\n share.value().len() !== secretLen\n ) {\n throw new SSKRError(SSKRErrorType.ShareSetInvalid);\n }\n }\n\n // sort shares into member groups\n let groupFound = false;\n for (const group of groups) {\n if (share.groupIndex() === group.groupIndex) {\n groupFound = true;\n if (share.memberThreshold() !== group.memberThreshold) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n for (const memberIndex of group.memberIndexes) {\n if (share.memberIndex() === memberIndex) {\n throw new SSKRError(SSKRErrorType.DuplicateMemberIndex);\n }\n }\n if (group.memberIndexes.length < group.memberThreshold) {\n group.memberIndexes.push(share.memberIndex());\n group.memberShares.push(share.value().clone());\n }\n }\n }\n\n if (!groupFound) {\n const g: Group = {\n groupIndex: share.groupIndex(),\n memberThreshold: share.memberThreshold(),\n memberIndexes: [share.memberIndex()],\n memberShares: [share.value().clone()],\n };\n groups.push(g);\n nextGroup++;\n }\n }\n\n // Check that we have enough groups to recover the master secret\n if (nextGroup < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Here, all of the shares are unpacked into member groups. Now we go\n // through each group and recover the group secret, and then use the\n // result to recover the master secret\n const masterIndexes: number[] = [];\n const masterShares: Uint8Array[] = [];\n\n for (const group of groups) {\n // Only attempt to recover the group secret if we have enough shares\n if (group.memberIndexes.length < group.memberThreshold) {\n continue;\n }\n\n // Recover the group secret\n try {\n const memberSharesData = group.memberShares.map((s) => s.getData());\n const groupSecret = recoverSecret(group.memberIndexes, memberSharesData);\n masterIndexes.push(group.groupIndex);\n masterShares.push(groupSecret);\n } catch {\n // If we can't recover this group, just skip it\n continue;\n }\n\n // Stop if we have enough groups to recover the master secret\n if (masterIndexes.length === groupThreshold) {\n break;\n }\n }\n\n // If we don't have enough groups to recover the master secret, return an error\n if (masterIndexes.length < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Recover the master secret\n let masterSecretData: Uint8Array;\n try {\n masterSecretData = recoverSecret(masterIndexes, masterShares);\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n return Secret.new(masterSecretData);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Blockchain Commons Sharded Secret Key Reconstruction (SSKR)\n// Ported from bc-sskr-rust\n//\n// Sharded Secret Key Reconstruction (SSKR) is a protocol for splitting a\n// secret into a set of shares across one or more groups, such that the\n// secret can be reconstructed from any combination of shares totaling or\n// exceeding a threshold number of shares within each group and across all\n// groups. SSKR is a generalization of Shamir's Secret Sharing (SSS) that\n// allows for multiple groups and multiple thresholds.\n\nimport {\n MIN_SECRET_LEN as SHAMIR_MIN_SECRET_LEN,\n MAX_SECRET_LEN as SHAMIR_MAX_SECRET_LEN,\n MAX_SHARE_COUNT as SHAMIR_MAX_SHARE_COUNT,\n} from \"@bcts/shamir\";\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = SHAMIR_MIN_SECRET_LEN;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = SHAMIR_MAX_SECRET_LEN;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = SHAMIR_MAX_SHARE_COUNT;\n\n/**\n * The maximum number of groups in a split.\n */\nexport const MAX_GROUPS_COUNT = MAX_SHARE_COUNT;\n\n/**\n * The number of bytes used to encode the metadata for a share.\n */\nexport const METADATA_SIZE_BYTES = 5;\n\n/**\n * The minimum number of bytes required to encode a share.\n */\nexport const MIN_SERIALIZE_SIZE_BYTES = METADATA_SIZE_BYTES + MIN_SECRET_LEN;\n\n// Error types\nexport { SSKRError, SSKRErrorType, type SSKRResult } from \"./error.js\";\n\n// Secret\nexport { Secret } from \"./secret.js\";\n\n// Specifications\nexport { GroupSpec, Spec } from \"./spec.js\";\n\n// Encoding/Decoding\nexport { sskrGenerate, sskrGenerateUsing, sskrCombine } from \"./encoding.js\";\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -35,6 +35,11 @@ declare class SSKRError extends Error {
|
|
|
35
35
|
type SSKRResult<T> = T;
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/secret.d.ts
|
|
38
|
+
/**
|
|
39
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
40
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
38
43
|
/**
|
|
39
44
|
* A secret to be split into shares.
|
|
40
45
|
*/
|
|
@@ -77,6 +82,11 @@ declare class Secret {
|
|
|
77
82
|
}
|
|
78
83
|
//#endregion
|
|
79
84
|
//#region src/spec.d.ts
|
|
85
|
+
/**
|
|
86
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
87
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
88
|
+
*
|
|
89
|
+
*/
|
|
80
90
|
/**
|
|
81
91
|
* A specification for a group of shares within an SSKR split.
|
|
82
92
|
*/
|
|
@@ -189,22 +199,27 @@ declare function sskrGenerateUsing(spec: Spec, masterSecret: Secret, randomGener
|
|
|
189
199
|
declare function sskrCombine(shares: Uint8Array[]): Secret;
|
|
190
200
|
//#endregion
|
|
191
201
|
//#region src/index.d.ts
|
|
202
|
+
/**
|
|
203
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
204
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
205
|
+
*
|
|
206
|
+
*/
|
|
192
207
|
/**
|
|
193
208
|
* The minimum length of a secret.
|
|
194
209
|
*/
|
|
195
|
-
declare const MIN_SECRET_LEN
|
|
210
|
+
declare const MIN_SECRET_LEN = 16;
|
|
196
211
|
/**
|
|
197
212
|
* The maximum length of a secret.
|
|
198
213
|
*/
|
|
199
|
-
declare const MAX_SECRET_LEN
|
|
214
|
+
declare const MAX_SECRET_LEN = 32;
|
|
200
215
|
/**
|
|
201
216
|
* The maximum number of shares that can be generated from a secret.
|
|
202
217
|
*/
|
|
203
|
-
declare const MAX_SHARE_COUNT
|
|
218
|
+
declare const MAX_SHARE_COUNT = 16;
|
|
204
219
|
/**
|
|
205
220
|
* The maximum number of groups in a split.
|
|
206
221
|
*/
|
|
207
|
-
declare const MAX_GROUPS_COUNT
|
|
222
|
+
declare const MAX_GROUPS_COUNT = 16;
|
|
208
223
|
/**
|
|
209
224
|
* The number of bytes used to encode the metadata for a share.
|
|
210
225
|
*/
|
|
@@ -212,7 +227,7 @@ declare const METADATA_SIZE_BYTES = 5;
|
|
|
212
227
|
/**
|
|
213
228
|
* The minimum number of bytes required to encode a share.
|
|
214
229
|
*/
|
|
215
|
-
declare const MIN_SERIALIZE_SIZE_BYTES:
|
|
230
|
+
declare const MIN_SERIALIZE_SIZE_BYTES: number;
|
|
216
231
|
//#endregion
|
|
217
232
|
export { GroupSpec, MAX_GROUPS_COUNT, MAX_SECRET_LEN, MAX_SHARE_COUNT, METADATA_SIZE_BYTES, MIN_SECRET_LEN, MIN_SERIALIZE_SIZE_BYTES, SSKRError, SSKRErrorType, type SSKRResult, Secret, Spec, sskrCombine, sskrGenerate, sskrGenerateUsing };
|
|
218
233
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.cts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/encoding.ts","../src/index.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.cts","names":[],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/encoding.ts","../src/index.ts"],"mappings":";;;;;;;aAaY,aAAA;EACV,oBAAA;EACA,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,kBAAA;EACA,sBAAA;EACA,eAAA;EACA,mBAAA;EACA,aAAA;EACA,cAAA;EACA,kBAAA;EACA,wBAAA;EACA,WAAA;EACA,eAAA;EACA,WAAA;AAAA;;;;cAMW,SAAA,SAAkB,KAAA;EAAA,SACpB,IAAA,EAAM,aAAA;EAAA,SACN,WAAA,GAAc,WAAA;cAEX,IAAA,EAAM,aAAA,EAAe,OAAA,WAAkB,WAAA,GAAc,WAAA;EAAA,eAOlD,cAAA;EAAA,OAqCR,eAAA,CAAgB,KAAA,EAAO,WAAA,GAAc,SAAA;AAAA;AAAA,KAKlC,UAAA,MAAgB,CAAA;;;;;;;AA1E5B;;;;cCCa,MAAA;EAAA,iBACM,IAAA;EAAA,QAEV,WAAA,CAAA;EDAP;;;;;;;;EAAA,OCYO,GAAA,CAAI,IAAA,EAAM,UAAA,YAAsB,MAAA;EDHvC;;;ECuBA,GAAA,CAAA;EDrBW;AAMb;;ECsBE,OAAA,CAAA;EDrBe;;;EC4Bf,OAAA,CAAA,GAAW,UAAA;EDmBmB;;;ECZ9B,KAAA,CAAA,GAAS,UAAA;EDpCyB;;;EC2ClC,MAAA,CAAO,KAAA,EAAO,MAAA;EDzCL;;;ECwDT,KAAA,CAAA,GAAS,MAAA;AAAA;;;;;;;AD/EX;;;;cECa,SAAA;EAAA,iBACM,gBAAA;EAAA,iBACA,YAAA;EAAA,QAEV,WAAA,CAAA;EFAP;;;;;;;;;;;EAAA,OEgBO,GAAA,CAAI,eAAA,UAAyB,WAAA,WAAsB,SAAA;EFN/C;AAMb;;EEgBE,eAAA,CAAA;EFfe;;;EEsBf,WAAA,CAAA;EFyB8B;;;;EAAA,OEjBvB,KAAA,CAAM,CAAA,WAAY,SAAA;EF/BI;;;EAAA,OEyDtB,OAAA,CAAA,GAAW,SAAA;EFvDK;;;EE8DvB,QAAA,CAAA;AAAA;;;;cAQW,IAAA;EAAA,iBACM,eAAA;EAAA,iBACA,OAAA;EAAA,QAEV,WAAA,CAAA;EF5B8C;;AAKvD;;;;;;;;ACzEA;;EDoEuD,OE6C9C,GAAA,CAAI,cAAA,UAAwB,MAAA,EAAQ,SAAA,KAAc,IAAA;EDlGxC;;;ECkHjB,cAAA,CAAA;EDlEc;;;ECyEd,MAAA,CAAA,GAAU,SAAA;EDvIO;;;EC8IjB,UAAA,CAAA;EDhIW;;;ECuIX,UAAA,CAAA;AAAA;;;;;;;;;;;iBC1Ic,YAAA,CAAa,IAAA,EAAM,IAAA,EAAM,YAAA,EAAc,MAAA,GAAS,UAAA;;;;;;;;;AHQhE;;;iBGQgB,iBAAA,CACd,IAAA,EAAM,IAAA,EACN,YAAA,EAAc,MAAA,EACd,eAAA,EAAiB,qBAAA,GAChB,UAAA;;;;;;;;;iBAgBa,WAAA,CAAY,MAAA,EAAQ,UAAA,KAAe,MAAA;;;;;;;AHjDnD;;;;cIYa,cAAA;;;;cAKA,cAAA;;;;cAKA,eAAA;;;;cAKA,gBAAA;;;;cAKA,mBAAA;AJXb;;;AAAA,cIgBa,wBAAA"}
|
package/dist/index.d.mts
CHANGED
|
@@ -35,6 +35,11 @@ declare class SSKRError extends Error {
|
|
|
35
35
|
type SSKRResult<T> = T;
|
|
36
36
|
//#endregion
|
|
37
37
|
//#region src/secret.d.ts
|
|
38
|
+
/**
|
|
39
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
40
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
41
|
+
*
|
|
42
|
+
*/
|
|
38
43
|
/**
|
|
39
44
|
* A secret to be split into shares.
|
|
40
45
|
*/
|
|
@@ -77,6 +82,11 @@ declare class Secret {
|
|
|
77
82
|
}
|
|
78
83
|
//#endregion
|
|
79
84
|
//#region src/spec.d.ts
|
|
85
|
+
/**
|
|
86
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
87
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
88
|
+
*
|
|
89
|
+
*/
|
|
80
90
|
/**
|
|
81
91
|
* A specification for a group of shares within an SSKR split.
|
|
82
92
|
*/
|
|
@@ -189,22 +199,27 @@ declare function sskrGenerateUsing(spec: Spec, masterSecret: Secret, randomGener
|
|
|
189
199
|
declare function sskrCombine(shares: Uint8Array[]): Secret;
|
|
190
200
|
//#endregion
|
|
191
201
|
//#region src/index.d.ts
|
|
202
|
+
/**
|
|
203
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
204
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
205
|
+
*
|
|
206
|
+
*/
|
|
192
207
|
/**
|
|
193
208
|
* The minimum length of a secret.
|
|
194
209
|
*/
|
|
195
|
-
declare const MIN_SECRET_LEN
|
|
210
|
+
declare const MIN_SECRET_LEN = 16;
|
|
196
211
|
/**
|
|
197
212
|
* The maximum length of a secret.
|
|
198
213
|
*/
|
|
199
|
-
declare const MAX_SECRET_LEN
|
|
214
|
+
declare const MAX_SECRET_LEN = 32;
|
|
200
215
|
/**
|
|
201
216
|
* The maximum number of shares that can be generated from a secret.
|
|
202
217
|
*/
|
|
203
|
-
declare const MAX_SHARE_COUNT
|
|
218
|
+
declare const MAX_SHARE_COUNT = 16;
|
|
204
219
|
/**
|
|
205
220
|
* The maximum number of groups in a split.
|
|
206
221
|
*/
|
|
207
|
-
declare const MAX_GROUPS_COUNT
|
|
222
|
+
declare const MAX_GROUPS_COUNT = 16;
|
|
208
223
|
/**
|
|
209
224
|
* The number of bytes used to encode the metadata for a share.
|
|
210
225
|
*/
|
|
@@ -212,7 +227,7 @@ declare const METADATA_SIZE_BYTES = 5;
|
|
|
212
227
|
/**
|
|
213
228
|
* The minimum number of bytes required to encode a share.
|
|
214
229
|
*/
|
|
215
|
-
declare const MIN_SERIALIZE_SIZE_BYTES:
|
|
230
|
+
declare const MIN_SERIALIZE_SIZE_BYTES: number;
|
|
216
231
|
//#endregion
|
|
217
232
|
export { GroupSpec, MAX_GROUPS_COUNT, MAX_SECRET_LEN, MAX_SHARE_COUNT, METADATA_SIZE_BYTES, MIN_SECRET_LEN, MIN_SERIALIZE_SIZE_BYTES, SSKRError, SSKRErrorType, type SSKRResult, Secret, Spec, sskrCombine, sskrGenerate, sskrGenerateUsing };
|
|
218
233
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/encoding.ts","../src/index.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/encoding.ts","../src/index.ts"],"mappings":";;;;;;;aAaY,aAAA;EACV,oBAAA;EACA,gBAAA;EACA,iBAAA;EACA,qBAAA;EACA,kBAAA;EACA,sBAAA;EACA,eAAA;EACA,mBAAA;EACA,aAAA;EACA,cAAA;EACA,kBAAA;EACA,wBAAA;EACA,WAAA;EACA,eAAA;EACA,WAAA;AAAA;;;;cAMW,SAAA,SAAkB,KAAA;EAAA,SACpB,IAAA,EAAM,aAAA;EAAA,SACN,WAAA,GAAc,WAAA;cAEX,IAAA,EAAM,aAAA,EAAe,OAAA,WAAkB,WAAA,GAAc,WAAA;EAAA,eAOlD,cAAA;EAAA,OAqCR,eAAA,CAAgB,KAAA,EAAO,WAAA,GAAc,SAAA;AAAA;AAAA,KAKlC,UAAA,MAAgB,CAAA;;;;;;;AA1E5B;;;;cCCa,MAAA;EAAA,iBACM,IAAA;EAAA,QAEV,WAAA,CAAA;EDAP;;;;;;;;EAAA,OCYO,GAAA,CAAI,IAAA,EAAM,UAAA,YAAsB,MAAA;EDHvC;;;ECuBA,GAAA,CAAA;EDrBW;AAMb;;ECsBE,OAAA,CAAA;EDrBe;;;EC4Bf,OAAA,CAAA,GAAW,UAAA;EDmBmB;;;ECZ9B,KAAA,CAAA,GAAS,UAAA;EDpCyB;;;EC2ClC,MAAA,CAAO,KAAA,EAAO,MAAA;EDzCL;;;ECwDT,KAAA,CAAA,GAAS,MAAA;AAAA;;;;;;;AD/EX;;;;cECa,SAAA;EAAA,iBACM,gBAAA;EAAA,iBACA,YAAA;EAAA,QAEV,WAAA,CAAA;EFAP;;;;;;;;;;;EAAA,OEgBO,GAAA,CAAI,eAAA,UAAyB,WAAA,WAAsB,SAAA;EFN/C;AAMb;;EEgBE,eAAA,CAAA;EFfe;;;EEsBf,WAAA,CAAA;EFyB8B;;;;EAAA,OEjBvB,KAAA,CAAM,CAAA,WAAY,SAAA;EF/BI;;;EAAA,OEyDtB,OAAA,CAAA,GAAW,SAAA;EFvDK;;;EE8DvB,QAAA,CAAA;AAAA;;;;cAQW,IAAA;EAAA,iBACM,eAAA;EAAA,iBACA,OAAA;EAAA,QAEV,WAAA,CAAA;EF5B8C;;AAKvD;;;;;;;;ACzEA;;EDoEuD,OE6C9C,GAAA,CAAI,cAAA,UAAwB,MAAA,EAAQ,SAAA,KAAc,IAAA;EDlGxC;;;ECkHjB,cAAA,CAAA;EDlEc;;;ECyEd,MAAA,CAAA,GAAU,SAAA;EDvIO;;;EC8IjB,UAAA,CAAA;EDhIW;;;ECuIX,UAAA,CAAA;AAAA;;;;;;;;;;;iBC1Ic,YAAA,CAAa,IAAA,EAAM,IAAA,EAAM,YAAA,EAAc,MAAA,GAAS,UAAA;;;;;;;;;AHQhE;;;iBGQgB,iBAAA,CACd,IAAA,EAAM,IAAA,EACN,YAAA,EAAc,MAAA,EACd,eAAA,EAAiB,qBAAA,GAChB,UAAA;;;;;;;;;iBAgBa,WAAA,CAAY,MAAA,EAAQ,UAAA,KAAe,MAAA;;;;;;;AHjDnD;;;;cIYa,cAAA;;;;cAKA,cAAA;;;;cAKA,eAAA;;;;cAKA,gBAAA;;;;cAKA,mBAAA;AJXb;;;AAAA,cIgBa,wBAAA"}
|
package/dist/index.iife.js
CHANGED
|
@@ -63,6 +63,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
63
63
|
//#endregion
|
|
64
64
|
//#region src/secret.ts
|
|
65
65
|
/**
|
|
66
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
67
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
68
|
+
*
|
|
69
|
+
*/
|
|
70
|
+
/**
|
|
66
71
|
* A secret to be split into shares.
|
|
67
72
|
*/
|
|
68
73
|
var Secret = class Secret {
|
|
@@ -129,6 +134,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
129
134
|
//#endregion
|
|
130
135
|
//#region src/spec.ts
|
|
131
136
|
/**
|
|
137
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
138
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
139
|
+
*
|
|
140
|
+
*/
|
|
141
|
+
/**
|
|
132
142
|
* A specification for a group of shares within an SSKR split.
|
|
133
143
|
*/
|
|
134
144
|
var GroupSpec = class GroupSpec {
|
|
@@ -462,6 +472,11 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
462
472
|
//#endregion
|
|
463
473
|
//#region src/index.ts
|
|
464
474
|
/**
|
|
475
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
476
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
477
|
+
*
|
|
478
|
+
*/
|
|
479
|
+
/**
|
|
465
480
|
* The minimum length of a secret.
|
|
466
481
|
*/
|
|
467
482
|
const MIN_SECRET_LEN = _bcts_shamir.MIN_SECRET_LEN;
|
package/dist/index.iife.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.iife.js","names":["MAX_SHARE_COUNT","SecureRandomNumberGenerator","ShamirError","SHAMIR_MIN_SECRET_LEN","SHAMIR_MAX_SECRET_LEN","SHAMIR_MAX_SHARE_COUNT"],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/share.ts","../src/encoding.ts","../src/index.ts"],"sourcesContent":["// Ported from bc-sskr-rust/src/error.rs\n\nimport type { ShamirError } from \"@bcts/shamir\";\n\n/**\n * Error types for SSKR operations.\n */\nexport enum SSKRErrorType {\n DuplicateMemberIndex = \"DuplicateMemberIndex\",\n GroupSpecInvalid = \"GroupSpecInvalid\",\n GroupCountInvalid = \"GroupCountInvalid\",\n GroupThresholdInvalid = \"GroupThresholdInvalid\",\n MemberCountInvalid = \"MemberCountInvalid\",\n MemberThresholdInvalid = \"MemberThresholdInvalid\",\n NotEnoughGroups = \"NotEnoughGroups\",\n SecretLengthNotEven = \"SecretLengthNotEven\",\n SecretTooLong = \"SecretTooLong\",\n SecretTooShort = \"SecretTooShort\",\n ShareLengthInvalid = \"ShareLengthInvalid\",\n ShareReservedBitsInvalid = \"ShareReservedBitsInvalid\",\n SharesEmpty = \"SharesEmpty\",\n ShareSetInvalid = \"ShareSetInvalid\",\n ShamirError = \"ShamirError\",\n}\n\n/**\n * Error class for SSKR operations.\n */\nexport class SSKRError extends Error {\n readonly type: SSKRErrorType;\n readonly shamirError?: ShamirError | undefined;\n\n constructor(type: SSKRErrorType, message?: string, shamirError?: ShamirError) {\n super(message ?? SSKRError.defaultMessage(type, shamirError));\n this.type = type;\n this.shamirError = shamirError;\n this.name = \"SSKRError\";\n }\n\n private static defaultMessage(type: SSKRErrorType, shamirError?: ShamirError): string {\n switch (type) {\n case SSKRErrorType.DuplicateMemberIndex:\n return \"When combining shares, the provided shares contained a duplicate member index\";\n case SSKRErrorType.GroupSpecInvalid:\n return \"Invalid group specification.\";\n case SSKRErrorType.GroupCountInvalid:\n return \"When creating a split spec, the group count is invalid\";\n case SSKRErrorType.GroupThresholdInvalid:\n return \"SSKR group threshold is invalid\";\n case SSKRErrorType.MemberCountInvalid:\n return \"SSKR member count is invalid\";\n case SSKRErrorType.MemberThresholdInvalid:\n return \"SSKR member threshold is invalid\";\n case SSKRErrorType.NotEnoughGroups:\n return \"SSKR shares did not contain enough groups\";\n case SSKRErrorType.SecretLengthNotEven:\n return \"SSKR secret is not of even length\";\n case SSKRErrorType.SecretTooLong:\n return \"SSKR secret is too long\";\n case SSKRErrorType.SecretTooShort:\n return \"SSKR secret is too short\";\n case SSKRErrorType.ShareLengthInvalid:\n return \"SSKR shares did not contain enough serialized bytes\";\n case SSKRErrorType.ShareReservedBitsInvalid:\n return \"SSKR shares contained invalid reserved bits\";\n case SSKRErrorType.SharesEmpty:\n return \"SSKR shares were empty\";\n case SSKRErrorType.ShareSetInvalid:\n return \"SSKR shares were invalid\";\n case SSKRErrorType.ShamirError:\n return shamirError != null\n ? `SSKR Shamir error: ${shamirError.message}`\n : \"SSKR Shamir error\";\n }\n }\n\n static fromShamirError(error: ShamirError): SSKRError {\n return new SSKRError(SSKRErrorType.ShamirError, undefined, error);\n }\n}\n\nexport type SSKRResult<T> = T;\n","// Ported from bc-sskr-rust/src/secret.rs\n\nimport { MIN_SECRET_LEN, MAX_SECRET_LEN } from \"./index.js\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A secret to be split into shares.\n */\nexport class Secret {\n private readonly data: Uint8Array;\n\n private constructor(data: Uint8Array) {\n this.data = data;\n }\n\n /**\n * Creates a new Secret instance with the given data.\n *\n * @param data - The secret data to be split into shares.\n * @returns A new Secret instance.\n * @throws SSKRError if the length of the secret is less than\n * MIN_SECRET_LEN, greater than MAX_SECRET_LEN, or not even.\n */\n static new(data: Uint8Array | string): Secret {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const len = bytes.length;\n\n if (len < MIN_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooShort);\n }\n if (len > MAX_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooLong);\n }\n if ((len & 1) !== 0) {\n throw new SSKRError(SSKRErrorType.SecretLengthNotEven);\n }\n\n return new Secret(new Uint8Array(bytes));\n }\n\n /**\n * Returns the length of the secret.\n */\n len(): number {\n return this.data.length;\n }\n\n /**\n * Returns true if the secret is empty.\n */\n isEmpty(): boolean {\n return this.len() === 0;\n }\n\n /**\n * Returns a reference to the secret data.\n */\n getData(): Uint8Array {\n return this.data;\n }\n\n /**\n * Returns the secret data as a Uint8Array.\n */\n asRef(): Uint8Array {\n return this.data;\n }\n\n /**\n * Check equality with another Secret.\n */\n equals(other: Secret): boolean {\n if (this.data.length !== other.data.length) {\n return false;\n }\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i] !== other.data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Clone the secret.\n */\n clone(): Secret {\n return new Secret(new Uint8Array(this.data));\n }\n}\n","// Ported from bc-sskr-rust/src/spec.rs\n\nimport { MAX_SHARE_COUNT } from \"@bcts/shamir\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A specification for a group of shares within an SSKR split.\n */\nexport class GroupSpec {\n private readonly _memberThreshold: number;\n private readonly _memberCount: number;\n\n private constructor(memberThreshold: number, memberCount: number) {\n this._memberThreshold = memberThreshold;\n this._memberCount = memberCount;\n }\n\n /**\n * Creates a new GroupSpec instance with the given member threshold and count.\n *\n * @param memberThreshold - The minimum number of member shares required to\n * reconstruct the secret within the group.\n * @param memberCount - The total number of member shares in the group.\n * @returns A new GroupSpec instance.\n * @throws SSKRError if the member count is zero, if the member count is\n * greater than the maximum share count, or if the member threshold is\n * greater than the member count.\n */\n static new(memberThreshold: number, memberCount: number): GroupSpec {\n if (memberCount === 0) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberCount > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberThreshold > memberCount) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n return new GroupSpec(memberThreshold, memberCount);\n }\n\n /**\n * Returns the member share threshold for this group.\n */\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n /**\n * Returns the number of member shares in this group.\n */\n memberCount(): number {\n return this._memberCount;\n }\n\n /**\n * Parses a group specification from a string.\n * Format: \"M-of-N\" where M is the threshold and N is the count.\n */\n static parse(s: string): GroupSpec {\n const parts = s.split(\"-\");\n if (parts.length !== 3) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberThreshold = parseInt(parts[0], 10);\n if (isNaN(memberThreshold)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n if (parts[1] !== \"of\") {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberCount = parseInt(parts[2], 10);\n if (isNaN(memberCount)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n return GroupSpec.new(memberThreshold, memberCount);\n }\n\n /**\n * Creates a default GroupSpec (1-of-1).\n */\n static default(): GroupSpec {\n return GroupSpec.new(1, 1);\n }\n\n /**\n * Returns a string representation of the group spec.\n */\n toString(): string {\n return `${this._memberThreshold}-of-${this._memberCount}`;\n }\n}\n\n/**\n * A specification for an SSKR split.\n */\nexport class Spec {\n private readonly _groupThreshold: number;\n private readonly _groups: GroupSpec[];\n\n private constructor(groupThreshold: number, groups: GroupSpec[]) {\n this._groupThreshold = groupThreshold;\n this._groups = groups;\n }\n\n /**\n * Creates a new Spec instance with the given group threshold and groups.\n *\n * @param groupThreshold - The minimum number of groups required to\n * reconstruct the secret.\n * @param groups - The list of GroupSpec instances that define the groups\n * and their members.\n * @returns A new Spec instance.\n * @throws SSKRError if the group threshold is zero, if the group threshold\n * is greater than the number of groups, or if the number of groups is\n * greater than the maximum share count.\n */\n static new(groupThreshold: number, groups: GroupSpec[]): Spec {\n if (groupThreshold === 0) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groupThreshold > groups.length) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groups.length > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.GroupCountInvalid);\n }\n return new Spec(groupThreshold, groups);\n }\n\n /**\n * Returns the group threshold.\n */\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n /**\n * Returns a slice of the group specifications.\n */\n groups(): GroupSpec[] {\n return this._groups;\n }\n\n /**\n * Returns the number of groups.\n */\n groupCount(): number {\n return this._groups.length;\n }\n\n /**\n * Returns the total number of shares across all groups.\n */\n shareCount(): number {\n return this._groups.reduce((sum, g) => sum + g.memberCount(), 0);\n }\n}\n","// Ported from bc-sskr-rust/src/share.rs\n\nimport type { Secret } from \"./secret.js\";\n\n/**\n * A share in the SSKR scheme.\n */\nexport class SSKRShare {\n private readonly _identifier: number;\n private readonly _groupIndex: number;\n private readonly _groupThreshold: number;\n private readonly _groupCount: number;\n private readonly _memberIndex: number;\n private readonly _memberThreshold: number;\n private readonly _value: Secret;\n\n constructor(\n identifier: number,\n groupIndex: number,\n groupThreshold: number,\n groupCount: number,\n memberIndex: number,\n memberThreshold: number,\n value: Secret,\n ) {\n this._identifier = identifier;\n this._groupIndex = groupIndex;\n this._groupThreshold = groupThreshold;\n this._groupCount = groupCount;\n this._memberIndex = memberIndex;\n this._memberThreshold = memberThreshold;\n this._value = value;\n }\n\n identifier(): number {\n return this._identifier;\n }\n\n groupIndex(): number {\n return this._groupIndex;\n }\n\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n groupCount(): number {\n return this._groupCount;\n }\n\n memberIndex(): number {\n return this._memberIndex;\n }\n\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n value(): Secret {\n return this._value;\n }\n}\n","// Ported from bc-sskr-rust/src/encoding.rs\n\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\nimport { SecureRandomNumberGenerator } from \"@bcts/rand\";\nimport { splitSecret, recoverSecret, ShamirError } from \"@bcts/shamir\";\n\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\nimport { Secret } from \"./secret.js\";\nimport type { Spec } from \"./spec.js\";\nimport { SSKRShare } from \"./share.js\";\nimport { METADATA_SIZE_BYTES } from \"./index.js\";\n\n/**\n * Generates SSKR shares for the given Spec and Secret.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerate(spec: Spec, masterSecret: Secret): Uint8Array[][] {\n const rng = new SecureRandomNumberGenerator();\n return sskrGenerateUsing(spec, masterSecret, rng);\n}\n\n/**\n * Generates SSKR shares for the given Spec and Secret using the provided\n * random number generator.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @param randomGenerator - The random number generator to use for generating\n * shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerateUsing(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[][] {\n const groupsShares = generateShares(spec, masterSecret, randomGenerator);\n\n const result: Uint8Array[][] = groupsShares.map((group) => group.map(serializeShare));\n\n return result;\n}\n\n/**\n * Combines the given SSKR shares into a Secret.\n *\n * @param shares - A array of SSKR shares to be combined.\n * @returns The reconstructed Secret.\n * @throws SSKRError if the shares do not meet the necessary quorum of groups\n * and member shares within each group.\n */\nexport function sskrCombine(shares: Uint8Array[]): Secret {\n const sskrShares: SSKRShare[] = [];\n\n for (const share of shares) {\n const sskrShare = deserializeShare(share);\n sskrShares.push(sskrShare);\n }\n\n return combineShares(sskrShares);\n}\n\nfunction serializeShare(share: SSKRShare): Uint8Array {\n // pack the id, group and member data into 5 bytes:\n // 76543210 76543210 76543210\n // 76543210 76543210\n // ----------------====----====----====----\n // identifier: 16\n // group-threshold: 4\n // group-count: 4\n // group-index: 4\n // member-threshold: 4\n // reserved (MUST be zero): 4\n // member-index: 4\n\n const valueData = share.value().getData();\n const result = new Uint8Array(valueData.length + METADATA_SIZE_BYTES);\n\n const id = share.identifier();\n const gt = (share.groupThreshold() - 1) & 0xf;\n const gc = (share.groupCount() - 1) & 0xf;\n const gi = share.groupIndex() & 0xf;\n const mt = (share.memberThreshold() - 1) & 0xf;\n const mi = share.memberIndex() & 0xf;\n\n const id1 = id >> 8;\n const id2 = id & 0xff;\n\n result[0] = id1;\n result[1] = id2;\n result[2] = (gt << 4) | gc;\n result[3] = (gi << 4) | mt;\n result[4] = mi;\n result.set(valueData, METADATA_SIZE_BYTES);\n\n return result;\n}\n\nfunction deserializeShare(source: Uint8Array): SSKRShare {\n if (source.length < METADATA_SIZE_BYTES) {\n throw new SSKRError(SSKRErrorType.ShareLengthInvalid);\n }\n\n const groupThreshold = (source[2] >> 4) + 1;\n const groupCount = (source[2] & 0xf) + 1;\n\n if (groupThreshold > groupCount) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n\n const identifier = (source[0] << 8) | source[1];\n const groupIndex = source[3] >> 4;\n const memberThreshold = (source[3] & 0xf) + 1;\n const reserved = source[4] >> 4;\n if (reserved !== 0) {\n throw new SSKRError(SSKRErrorType.ShareReservedBitsInvalid);\n }\n const memberIndex = source[4] & 0xf;\n const value = Secret.new(source.subarray(METADATA_SIZE_BYTES));\n\n return new SSKRShare(\n identifier,\n groupIndex,\n groupThreshold,\n groupCount,\n memberIndex,\n memberThreshold,\n value,\n );\n}\n\nfunction generateShares(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): SSKRShare[][] {\n // assign a random identifier\n const identifierBytes = new Uint8Array(2);\n randomGenerator.fillRandomData(identifierBytes);\n const identifier = (identifierBytes[0] << 8) | identifierBytes[1];\n\n const groupsShares: SSKRShare[][] = [];\n\n let groupSecrets: Uint8Array[];\n try {\n groupSecrets = splitSecret(\n spec.groupThreshold(),\n spec.groupCount(),\n masterSecret.getData(),\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n for (let groupIndex = 0; groupIndex < spec.groups().length; groupIndex++) {\n const group = spec.groups()[groupIndex];\n const groupSecret = groupSecrets[groupIndex];\n\n let memberSecrets: Uint8Array[];\n try {\n memberSecrets = splitSecret(\n group.memberThreshold(),\n group.memberCount(),\n groupSecret,\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n const memberSSKRShares: SSKRShare[] = memberSecrets.map((memberSecret, memberIndex) => {\n const secret = Secret.new(memberSecret);\n return new SSKRShare(\n identifier,\n groupIndex,\n spec.groupThreshold(),\n spec.groupCount(),\n memberIndex,\n group.memberThreshold(),\n secret,\n );\n });\n\n groupsShares.push(memberSSKRShares);\n }\n\n return groupsShares;\n}\n\ninterface Group {\n groupIndex: number;\n memberThreshold: number;\n memberIndexes: number[];\n memberShares: Secret[];\n}\n\nfunction combineShares(shares: SSKRShare[]): Secret {\n let identifier = 0;\n let groupThreshold = 0;\n let groupCount = 0;\n\n if (shares.length === 0) {\n throw new SSKRError(SSKRErrorType.SharesEmpty);\n }\n\n let nextGroup = 0;\n const groups: Group[] = [];\n let secretLen = 0;\n\n for (let i = 0; i < shares.length; i++) {\n const share = shares[i];\n\n if (i === 0) {\n // on the first one, establish expected values for common metadata\n identifier = share.identifier();\n groupCount = share.groupCount();\n groupThreshold = share.groupThreshold();\n secretLen = share.value().len();\n } else {\n // on subsequent shares, check that common metadata matches\n if (\n share.identifier() !== identifier ||\n share.groupThreshold() !== groupThreshold ||\n share.groupCount() !== groupCount ||\n share.value().len() !== secretLen\n ) {\n throw new SSKRError(SSKRErrorType.ShareSetInvalid);\n }\n }\n\n // sort shares into member groups\n let groupFound = false;\n for (const group of groups) {\n if (share.groupIndex() === group.groupIndex) {\n groupFound = true;\n if (share.memberThreshold() !== group.memberThreshold) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n for (const memberIndex of group.memberIndexes) {\n if (share.memberIndex() === memberIndex) {\n throw new SSKRError(SSKRErrorType.DuplicateMemberIndex);\n }\n }\n if (group.memberIndexes.length < group.memberThreshold) {\n group.memberIndexes.push(share.memberIndex());\n group.memberShares.push(share.value().clone());\n }\n }\n }\n\n if (!groupFound) {\n const g: Group = {\n groupIndex: share.groupIndex(),\n memberThreshold: share.memberThreshold(),\n memberIndexes: [share.memberIndex()],\n memberShares: [share.value().clone()],\n };\n groups.push(g);\n nextGroup++;\n }\n }\n\n // Check that we have enough groups to recover the master secret\n if (nextGroup < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Here, all of the shares are unpacked into member groups. Now we go\n // through each group and recover the group secret, and then use the\n // result to recover the master secret\n const masterIndexes: number[] = [];\n const masterShares: Uint8Array[] = [];\n\n for (const group of groups) {\n // Only attempt to recover the group secret if we have enough shares\n if (group.memberIndexes.length < group.memberThreshold) {\n continue;\n }\n\n // Recover the group secret\n try {\n const memberSharesData = group.memberShares.map((s) => s.getData());\n const groupSecret = recoverSecret(group.memberIndexes, memberSharesData);\n masterIndexes.push(group.groupIndex);\n masterShares.push(groupSecret);\n } catch {\n // If we can't recover this group, just skip it\n continue;\n }\n\n // Stop if we have enough groups to recover the master secret\n if (masterIndexes.length === groupThreshold) {\n break;\n }\n }\n\n // If we don't have enough groups to recover the master secret, return an error\n if (masterIndexes.length < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Recover the master secret\n let masterSecretData: Uint8Array;\n try {\n masterSecretData = recoverSecret(masterIndexes, masterShares);\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n return Secret.new(masterSecretData);\n}\n","// Blockchain Commons Sharded Secret Key Reconstruction (SSKR)\n// Ported from bc-sskr-rust\n//\n// Sharded Secret Key Reconstruction (SSKR) is a protocol for splitting a\n// secret into a set of shares across one or more groups, such that the\n// secret can be reconstructed from any combination of shares totaling or\n// exceeding a threshold number of shares within each group and across all\n// groups. SSKR is a generalization of Shamir's Secret Sharing (SSS) that\n// allows for multiple groups and multiple thresholds.\n\nimport {\n MIN_SECRET_LEN as SHAMIR_MIN_SECRET_LEN,\n MAX_SECRET_LEN as SHAMIR_MAX_SECRET_LEN,\n MAX_SHARE_COUNT as SHAMIR_MAX_SHARE_COUNT,\n} from \"@bcts/shamir\";\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = SHAMIR_MIN_SECRET_LEN;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = SHAMIR_MAX_SECRET_LEN;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = SHAMIR_MAX_SHARE_COUNT;\n\n/**\n * The maximum number of groups in a split.\n */\nexport const MAX_GROUPS_COUNT = MAX_SHARE_COUNT;\n\n/**\n * The number of bytes used to encode the metadata for a share.\n */\nexport const METADATA_SIZE_BYTES = 5;\n\n/**\n * The minimum number of bytes required to encode a share.\n */\nexport const MIN_SERIALIZE_SIZE_BYTES = METADATA_SIZE_BYTES + MIN_SECRET_LEN;\n\n// Error types\nexport { SSKRError, SSKRErrorType, type SSKRResult } from \"./error.js\";\n\n// Secret\nexport { Secret } from \"./secret.js\";\n\n// Specifications\nexport { GroupSpec, Spec } from \"./spec.js\";\n\n// Encoding/Decoding\nexport { sskrGenerate, sskrGenerateUsing, sskrCombine } from \"./encoding.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.iife.js","names":["MAX_SHARE_COUNT","SecureRandomNumberGenerator","ShamirError","SHAMIR_MIN_SECRET_LEN","SHAMIR_MAX_SECRET_LEN","SHAMIR_MAX_SHARE_COUNT"],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/share.ts","../src/encoding.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-sskr-rust/src/error.rs\n\nimport type { ShamirError } from \"@bcts/shamir\";\n\n/**\n * Error types for SSKR operations.\n */\nexport enum SSKRErrorType {\n DuplicateMemberIndex = \"DuplicateMemberIndex\",\n GroupSpecInvalid = \"GroupSpecInvalid\",\n GroupCountInvalid = \"GroupCountInvalid\",\n GroupThresholdInvalid = \"GroupThresholdInvalid\",\n MemberCountInvalid = \"MemberCountInvalid\",\n MemberThresholdInvalid = \"MemberThresholdInvalid\",\n NotEnoughGroups = \"NotEnoughGroups\",\n SecretLengthNotEven = \"SecretLengthNotEven\",\n SecretTooLong = \"SecretTooLong\",\n SecretTooShort = \"SecretTooShort\",\n ShareLengthInvalid = \"ShareLengthInvalid\",\n ShareReservedBitsInvalid = \"ShareReservedBitsInvalid\",\n SharesEmpty = \"SharesEmpty\",\n ShareSetInvalid = \"ShareSetInvalid\",\n ShamirError = \"ShamirError\",\n}\n\n/**\n * Error class for SSKR operations.\n */\nexport class SSKRError extends Error {\n readonly type: SSKRErrorType;\n readonly shamirError?: ShamirError | undefined;\n\n constructor(type: SSKRErrorType, message?: string, shamirError?: ShamirError) {\n super(message ?? SSKRError.defaultMessage(type, shamirError));\n this.type = type;\n this.shamirError = shamirError;\n this.name = \"SSKRError\";\n }\n\n private static defaultMessage(type: SSKRErrorType, shamirError?: ShamirError): string {\n switch (type) {\n case SSKRErrorType.DuplicateMemberIndex:\n return \"When combining shares, the provided shares contained a duplicate member index\";\n case SSKRErrorType.GroupSpecInvalid:\n return \"Invalid group specification.\";\n case SSKRErrorType.GroupCountInvalid:\n return \"When creating a split spec, the group count is invalid\";\n case SSKRErrorType.GroupThresholdInvalid:\n return \"SSKR group threshold is invalid\";\n case SSKRErrorType.MemberCountInvalid:\n return \"SSKR member count is invalid\";\n case SSKRErrorType.MemberThresholdInvalid:\n return \"SSKR member threshold is invalid\";\n case SSKRErrorType.NotEnoughGroups:\n return \"SSKR shares did not contain enough groups\";\n case SSKRErrorType.SecretLengthNotEven:\n return \"SSKR secret is not of even length\";\n case SSKRErrorType.SecretTooLong:\n return \"SSKR secret is too long\";\n case SSKRErrorType.SecretTooShort:\n return \"SSKR secret is too short\";\n case SSKRErrorType.ShareLengthInvalid:\n return \"SSKR shares did not contain enough serialized bytes\";\n case SSKRErrorType.ShareReservedBitsInvalid:\n return \"SSKR shares contained invalid reserved bits\";\n case SSKRErrorType.SharesEmpty:\n return \"SSKR shares were empty\";\n case SSKRErrorType.ShareSetInvalid:\n return \"SSKR shares were invalid\";\n case SSKRErrorType.ShamirError:\n return shamirError != null\n ? `SSKR Shamir error: ${shamirError.message}`\n : \"SSKR Shamir error\";\n }\n }\n\n static fromShamirError(error: ShamirError): SSKRError {\n return new SSKRError(SSKRErrorType.ShamirError, undefined, error);\n }\n}\n\nexport type SSKRResult<T> = T;\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/secret.rs\n\nimport { MIN_SECRET_LEN, MAX_SECRET_LEN } from \"./index.js\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A secret to be split into shares.\n */\nexport class Secret {\n private readonly data: Uint8Array;\n\n private constructor(data: Uint8Array) {\n this.data = data;\n }\n\n /**\n * Creates a new Secret instance with the given data.\n *\n * @param data - The secret data to be split into shares.\n * @returns A new Secret instance.\n * @throws SSKRError if the length of the secret is less than\n * MIN_SECRET_LEN, greater than MAX_SECRET_LEN, or not even.\n */\n static new(data: Uint8Array | string): Secret {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const len = bytes.length;\n\n if (len < MIN_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooShort);\n }\n if (len > MAX_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooLong);\n }\n if ((len & 1) !== 0) {\n throw new SSKRError(SSKRErrorType.SecretLengthNotEven);\n }\n\n return new Secret(new Uint8Array(bytes));\n }\n\n /**\n * Returns the length of the secret.\n */\n len(): number {\n return this.data.length;\n }\n\n /**\n * Returns true if the secret is empty.\n */\n isEmpty(): boolean {\n return this.len() === 0;\n }\n\n /**\n * Returns a reference to the secret data.\n */\n getData(): Uint8Array {\n return this.data;\n }\n\n /**\n * Returns the secret data as a Uint8Array.\n */\n asRef(): Uint8Array {\n return this.data;\n }\n\n /**\n * Check equality with another Secret.\n */\n equals(other: Secret): boolean {\n if (this.data.length !== other.data.length) {\n return false;\n }\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i] !== other.data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Clone the secret.\n */\n clone(): Secret {\n return new Secret(new Uint8Array(this.data));\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/spec.rs\n\nimport { MAX_SHARE_COUNT } from \"@bcts/shamir\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A specification for a group of shares within an SSKR split.\n */\nexport class GroupSpec {\n private readonly _memberThreshold: number;\n private readonly _memberCount: number;\n\n private constructor(memberThreshold: number, memberCount: number) {\n this._memberThreshold = memberThreshold;\n this._memberCount = memberCount;\n }\n\n /**\n * Creates a new GroupSpec instance with the given member threshold and count.\n *\n * @param memberThreshold - The minimum number of member shares required to\n * reconstruct the secret within the group.\n * @param memberCount - The total number of member shares in the group.\n * @returns A new GroupSpec instance.\n * @throws SSKRError if the member count is zero, if the member count is\n * greater than the maximum share count, or if the member threshold is\n * greater than the member count.\n */\n static new(memberThreshold: number, memberCount: number): GroupSpec {\n if (memberCount === 0) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberCount > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberThreshold > memberCount) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n return new GroupSpec(memberThreshold, memberCount);\n }\n\n /**\n * Returns the member share threshold for this group.\n */\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n /**\n * Returns the number of member shares in this group.\n */\n memberCount(): number {\n return this._memberCount;\n }\n\n /**\n * Parses a group specification from a string.\n * Format: \"M-of-N\" where M is the threshold and N is the count.\n */\n static parse(s: string): GroupSpec {\n const parts = s.split(\"-\");\n if (parts.length !== 3) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberThreshold = parseInt(parts[0], 10);\n if (isNaN(memberThreshold)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n if (parts[1] !== \"of\") {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberCount = parseInt(parts[2], 10);\n if (isNaN(memberCount)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n return GroupSpec.new(memberThreshold, memberCount);\n }\n\n /**\n * Creates a default GroupSpec (1-of-1).\n */\n static default(): GroupSpec {\n return GroupSpec.new(1, 1);\n }\n\n /**\n * Returns a string representation of the group spec.\n */\n toString(): string {\n return `${this._memberThreshold}-of-${this._memberCount}`;\n }\n}\n\n/**\n * A specification for an SSKR split.\n */\nexport class Spec {\n private readonly _groupThreshold: number;\n private readonly _groups: GroupSpec[];\n\n private constructor(groupThreshold: number, groups: GroupSpec[]) {\n this._groupThreshold = groupThreshold;\n this._groups = groups;\n }\n\n /**\n * Creates a new Spec instance with the given group threshold and groups.\n *\n * @param groupThreshold - The minimum number of groups required to\n * reconstruct the secret.\n * @param groups - The list of GroupSpec instances that define the groups\n * and their members.\n * @returns A new Spec instance.\n * @throws SSKRError if the group threshold is zero, if the group threshold\n * is greater than the number of groups, or if the number of groups is\n * greater than the maximum share count.\n */\n static new(groupThreshold: number, groups: GroupSpec[]): Spec {\n if (groupThreshold === 0) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groupThreshold > groups.length) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groups.length > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.GroupCountInvalid);\n }\n return new Spec(groupThreshold, groups);\n }\n\n /**\n * Returns the group threshold.\n */\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n /**\n * Returns a slice of the group specifications.\n */\n groups(): GroupSpec[] {\n return this._groups;\n }\n\n /**\n * Returns the number of groups.\n */\n groupCount(): number {\n return this._groups.length;\n }\n\n /**\n * Returns the total number of shares across all groups.\n */\n shareCount(): number {\n return this._groups.reduce((sum, g) => sum + g.memberCount(), 0);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/share.rs\n\nimport type { Secret } from \"./secret.js\";\n\n/**\n * A share in the SSKR scheme.\n */\nexport class SSKRShare {\n private readonly _identifier: number;\n private readonly _groupIndex: number;\n private readonly _groupThreshold: number;\n private readonly _groupCount: number;\n private readonly _memberIndex: number;\n private readonly _memberThreshold: number;\n private readonly _value: Secret;\n\n constructor(\n identifier: number,\n groupIndex: number,\n groupThreshold: number,\n groupCount: number,\n memberIndex: number,\n memberThreshold: number,\n value: Secret,\n ) {\n this._identifier = identifier;\n this._groupIndex = groupIndex;\n this._groupThreshold = groupThreshold;\n this._groupCount = groupCount;\n this._memberIndex = memberIndex;\n this._memberThreshold = memberThreshold;\n this._value = value;\n }\n\n identifier(): number {\n return this._identifier;\n }\n\n groupIndex(): number {\n return this._groupIndex;\n }\n\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n groupCount(): number {\n return this._groupCount;\n }\n\n memberIndex(): number {\n return this._memberIndex;\n }\n\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n value(): Secret {\n return this._value;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/encoding.rs\n\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\nimport { SecureRandomNumberGenerator } from \"@bcts/rand\";\nimport { splitSecret, recoverSecret, ShamirError } from \"@bcts/shamir\";\n\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\nimport { Secret } from \"./secret.js\";\nimport type { Spec } from \"./spec.js\";\nimport { SSKRShare } from \"./share.js\";\nimport { METADATA_SIZE_BYTES } from \"./index.js\";\n\n/**\n * Generates SSKR shares for the given Spec and Secret.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerate(spec: Spec, masterSecret: Secret): Uint8Array[][] {\n const rng = new SecureRandomNumberGenerator();\n return sskrGenerateUsing(spec, masterSecret, rng);\n}\n\n/**\n * Generates SSKR shares for the given Spec and Secret using the provided\n * random number generator.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @param randomGenerator - The random number generator to use for generating\n * shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerateUsing(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[][] {\n const groupsShares = generateShares(spec, masterSecret, randomGenerator);\n\n const result: Uint8Array[][] = groupsShares.map((group) => group.map(serializeShare));\n\n return result;\n}\n\n/**\n * Combines the given SSKR shares into a Secret.\n *\n * @param shares - A array of SSKR shares to be combined.\n * @returns The reconstructed Secret.\n * @throws SSKRError if the shares do not meet the necessary quorum of groups\n * and member shares within each group.\n */\nexport function sskrCombine(shares: Uint8Array[]): Secret {\n const sskrShares: SSKRShare[] = [];\n\n for (const share of shares) {\n const sskrShare = deserializeShare(share);\n sskrShares.push(sskrShare);\n }\n\n return combineShares(sskrShares);\n}\n\nfunction serializeShare(share: SSKRShare): Uint8Array {\n // pack the id, group and member data into 5 bytes:\n // 76543210 76543210 76543210\n // 76543210 76543210\n // ----------------====----====----====----\n // identifier: 16\n // group-threshold: 4\n // group-count: 4\n // group-index: 4\n // member-threshold: 4\n // reserved (MUST be zero): 4\n // member-index: 4\n\n const valueData = share.value().getData();\n const result = new Uint8Array(valueData.length + METADATA_SIZE_BYTES);\n\n const id = share.identifier();\n const gt = (share.groupThreshold() - 1) & 0xf;\n const gc = (share.groupCount() - 1) & 0xf;\n const gi = share.groupIndex() & 0xf;\n const mt = (share.memberThreshold() - 1) & 0xf;\n const mi = share.memberIndex() & 0xf;\n\n const id1 = id >> 8;\n const id2 = id & 0xff;\n\n result[0] = id1;\n result[1] = id2;\n result[2] = (gt << 4) | gc;\n result[3] = (gi << 4) | mt;\n result[4] = mi;\n result.set(valueData, METADATA_SIZE_BYTES);\n\n return result;\n}\n\nfunction deserializeShare(source: Uint8Array): SSKRShare {\n if (source.length < METADATA_SIZE_BYTES) {\n throw new SSKRError(SSKRErrorType.ShareLengthInvalid);\n }\n\n const groupThreshold = (source[2] >> 4) + 1;\n const groupCount = (source[2] & 0xf) + 1;\n\n if (groupThreshold > groupCount) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n\n const identifier = (source[0] << 8) | source[1];\n const groupIndex = source[3] >> 4;\n const memberThreshold = (source[3] & 0xf) + 1;\n const reserved = source[4] >> 4;\n if (reserved !== 0) {\n throw new SSKRError(SSKRErrorType.ShareReservedBitsInvalid);\n }\n const memberIndex = source[4] & 0xf;\n const value = Secret.new(source.subarray(METADATA_SIZE_BYTES));\n\n return new SSKRShare(\n identifier,\n groupIndex,\n groupThreshold,\n groupCount,\n memberIndex,\n memberThreshold,\n value,\n );\n}\n\nfunction generateShares(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): SSKRShare[][] {\n // assign a random identifier\n const identifierBytes = new Uint8Array(2);\n randomGenerator.fillRandomData(identifierBytes);\n const identifier = (identifierBytes[0] << 8) | identifierBytes[1];\n\n const groupsShares: SSKRShare[][] = [];\n\n let groupSecrets: Uint8Array[];\n try {\n groupSecrets = splitSecret(\n spec.groupThreshold(),\n spec.groupCount(),\n masterSecret.getData(),\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n for (let groupIndex = 0; groupIndex < spec.groups().length; groupIndex++) {\n const group = spec.groups()[groupIndex];\n const groupSecret = groupSecrets[groupIndex];\n\n let memberSecrets: Uint8Array[];\n try {\n memberSecrets = splitSecret(\n group.memberThreshold(),\n group.memberCount(),\n groupSecret,\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n const memberSSKRShares: SSKRShare[] = memberSecrets.map((memberSecret, memberIndex) => {\n const secret = Secret.new(memberSecret);\n return new SSKRShare(\n identifier,\n groupIndex,\n spec.groupThreshold(),\n spec.groupCount(),\n memberIndex,\n group.memberThreshold(),\n secret,\n );\n });\n\n groupsShares.push(memberSSKRShares);\n }\n\n return groupsShares;\n}\n\ninterface Group {\n groupIndex: number;\n memberThreshold: number;\n memberIndexes: number[];\n memberShares: Secret[];\n}\n\nfunction combineShares(shares: SSKRShare[]): Secret {\n let identifier = 0;\n let groupThreshold = 0;\n let groupCount = 0;\n\n if (shares.length === 0) {\n throw new SSKRError(SSKRErrorType.SharesEmpty);\n }\n\n let nextGroup = 0;\n const groups: Group[] = [];\n let secretLen = 0;\n\n for (let i = 0; i < shares.length; i++) {\n const share = shares[i];\n\n if (i === 0) {\n // on the first one, establish expected values for common metadata\n identifier = share.identifier();\n groupCount = share.groupCount();\n groupThreshold = share.groupThreshold();\n secretLen = share.value().len();\n } else {\n // on subsequent shares, check that common metadata matches\n if (\n share.identifier() !== identifier ||\n share.groupThreshold() !== groupThreshold ||\n share.groupCount() !== groupCount ||\n share.value().len() !== secretLen\n ) {\n throw new SSKRError(SSKRErrorType.ShareSetInvalid);\n }\n }\n\n // sort shares into member groups\n let groupFound = false;\n for (const group of groups) {\n if (share.groupIndex() === group.groupIndex) {\n groupFound = true;\n if (share.memberThreshold() !== group.memberThreshold) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n for (const memberIndex of group.memberIndexes) {\n if (share.memberIndex() === memberIndex) {\n throw new SSKRError(SSKRErrorType.DuplicateMemberIndex);\n }\n }\n if (group.memberIndexes.length < group.memberThreshold) {\n group.memberIndexes.push(share.memberIndex());\n group.memberShares.push(share.value().clone());\n }\n }\n }\n\n if (!groupFound) {\n const g: Group = {\n groupIndex: share.groupIndex(),\n memberThreshold: share.memberThreshold(),\n memberIndexes: [share.memberIndex()],\n memberShares: [share.value().clone()],\n };\n groups.push(g);\n nextGroup++;\n }\n }\n\n // Check that we have enough groups to recover the master secret\n if (nextGroup < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Here, all of the shares are unpacked into member groups. Now we go\n // through each group and recover the group secret, and then use the\n // result to recover the master secret\n const masterIndexes: number[] = [];\n const masterShares: Uint8Array[] = [];\n\n for (const group of groups) {\n // Only attempt to recover the group secret if we have enough shares\n if (group.memberIndexes.length < group.memberThreshold) {\n continue;\n }\n\n // Recover the group secret\n try {\n const memberSharesData = group.memberShares.map((s) => s.getData());\n const groupSecret = recoverSecret(group.memberIndexes, memberSharesData);\n masterIndexes.push(group.groupIndex);\n masterShares.push(groupSecret);\n } catch {\n // If we can't recover this group, just skip it\n continue;\n }\n\n // Stop if we have enough groups to recover the master secret\n if (masterIndexes.length === groupThreshold) {\n break;\n }\n }\n\n // If we don't have enough groups to recover the master secret, return an error\n if (masterIndexes.length < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Recover the master secret\n let masterSecretData: Uint8Array;\n try {\n masterSecretData = recoverSecret(masterIndexes, masterShares);\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n return Secret.new(masterSecretData);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Blockchain Commons Sharded Secret Key Reconstruction (SSKR)\n// Ported from bc-sskr-rust\n//\n// Sharded Secret Key Reconstruction (SSKR) is a protocol for splitting a\n// secret into a set of shares across one or more groups, such that the\n// secret can be reconstructed from any combination of shares totaling or\n// exceeding a threshold number of shares within each group and across all\n// groups. SSKR is a generalization of Shamir's Secret Sharing (SSS) that\n// allows for multiple groups and multiple thresholds.\n\nimport {\n MIN_SECRET_LEN as SHAMIR_MIN_SECRET_LEN,\n MAX_SECRET_LEN as SHAMIR_MAX_SECRET_LEN,\n MAX_SHARE_COUNT as SHAMIR_MAX_SHARE_COUNT,\n} from \"@bcts/shamir\";\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = SHAMIR_MIN_SECRET_LEN;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = SHAMIR_MAX_SECRET_LEN;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = SHAMIR_MAX_SHARE_COUNT;\n\n/**\n * The maximum number of groups in a split.\n */\nexport const MAX_GROUPS_COUNT = MAX_SHARE_COUNT;\n\n/**\n * The number of bytes used to encode the metadata for a share.\n */\nexport const METADATA_SIZE_BYTES = 5;\n\n/**\n * The minimum number of bytes required to encode a share.\n */\nexport const MIN_SERIALIZE_SIZE_BYTES = METADATA_SIZE_BYTES + MIN_SECRET_LEN;\n\n// Error types\nexport { SSKRError, SSKRErrorType, type SSKRResult } from \"./error.js\";\n\n// Secret\nexport { Secret } from \"./secret.js\";\n\n// Specifications\nexport { GroupSpec, Spec } from \"./spec.js\";\n\n// Encoding/Decoding\nexport { sskrGenerate, sskrGenerateUsing, sskrCombine } from \"./encoding.js\";\n"],"mappings":";;;;;;;;CAaA,IAAY,wDAAL;AACL;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;CAMF,IAAa,YAAb,MAAa,kBAAkB,MAAM;EACnC,AAAS;EACT,AAAS;EAET,YAAY,MAAqB,SAAkB,aAA2B;AAC5E,SAAM,WAAW,UAAU,eAAe,MAAM,YAAY,CAAC;AAC7D,QAAK,OAAO;AACZ,QAAK,cAAc;AACnB,QAAK,OAAO;;EAGd,OAAe,eAAe,MAAqB,aAAmC;AACpF,WAAQ,MAAR;IACE,KAAK,cAAc,qBACjB,QAAO;IACT,KAAK,cAAc,iBACjB,QAAO;IACT,KAAK,cAAc,kBACjB,QAAO;IACT,KAAK,cAAc,sBACjB,QAAO;IACT,KAAK,cAAc,mBACjB,QAAO;IACT,KAAK,cAAc,uBACjB,QAAO;IACT,KAAK,cAAc,gBACjB,QAAO;IACT,KAAK,cAAc,oBACjB,QAAO;IACT,KAAK,cAAc,cACjB,QAAO;IACT,KAAK,cAAc,eACjB,QAAO;IACT,KAAK,cAAc,mBACjB,QAAO;IACT,KAAK,cAAc,yBACjB,QAAO;IACT,KAAK,cAAc,YACjB,QAAO;IACT,KAAK,cAAc,gBACjB,QAAO;IACT,KAAK,cAAc,YACjB,QAAO,eAAe,OAClB,sBAAsB,YAAY,YAClC;;;EAIV,OAAO,gBAAgB,OAA+B;AACpD,UAAO,IAAI,UAAU,cAAc,aAAa,QAAW,MAAM;;;;;;;;;;;;;;CCrErE,IAAa,SAAb,MAAa,OAAO;EAClB,AAAiB;EAEjB,AAAQ,YAAY,MAAkB;AACpC,QAAK,OAAO;;;;;;;;;;EAWd,OAAO,IAAI,MAAmC;GAC5C,MAAM,QAAQ,OAAO,SAAS,WAAW,IAAI,aAAa,CAAC,OAAO,KAAK,GAAG;GAC1E,MAAM,MAAM,MAAM;AAElB,OAAI,MAAM,eACR,OAAM,IAAI,UAAU,cAAc,eAAe;AAEnD,OAAI,MAAM,eACR,OAAM,IAAI,UAAU,cAAc,cAAc;AAElD,QAAK,MAAM,OAAO,EAChB,OAAM,IAAI,UAAU,cAAc,oBAAoB;AAGxD,UAAO,IAAI,OAAO,IAAI,WAAW,MAAM,CAAC;;;;;EAM1C,MAAc;AACZ,UAAO,KAAK,KAAK;;;;;EAMnB,UAAmB;AACjB,UAAO,KAAK,KAAK,KAAK;;;;;EAMxB,UAAsB;AACpB,UAAO,KAAK;;;;;EAMd,QAAoB;AAClB,UAAO,KAAK;;;;;EAMd,OAAO,OAAwB;AAC7B,OAAI,KAAK,KAAK,WAAW,MAAM,KAAK,OAClC,QAAO;AAET,QAAK,IAAI,IAAI,GAAG,IAAI,KAAK,KAAK,QAAQ,IACpC,KAAI,KAAK,KAAK,OAAO,MAAM,KAAK,GAC9B,QAAO;AAGX,UAAO;;;;;EAMT,QAAgB;AACd,UAAO,IAAI,OAAO,IAAI,WAAW,KAAK,KAAK,CAAC;;;;;;;;;;;;;;CC/EhD,IAAa,YAAb,MAAa,UAAU;EACrB,AAAiB;EACjB,AAAiB;EAEjB,AAAQ,YAAY,iBAAyB,aAAqB;AAChE,QAAK,mBAAmB;AACxB,QAAK,eAAe;;;;;;;;;;;;;EActB,OAAO,IAAI,iBAAyB,aAAgC;AAClE,OAAI,gBAAgB,EAClB,OAAM,IAAI,UAAU,cAAc,mBAAmB;AAEvD,OAAI,cAAcA,6BAChB,OAAM,IAAI,UAAU,cAAc,mBAAmB;AAEvD,OAAI,kBAAkB,YACpB,OAAM,IAAI,UAAU,cAAc,uBAAuB;AAE3D,UAAO,IAAI,UAAU,iBAAiB,YAAY;;;;;EAMpD,kBAA0B;AACxB,UAAO,KAAK;;;;;EAMd,cAAsB;AACpB,UAAO,KAAK;;;;;;EAOd,OAAO,MAAM,GAAsB;GACjC,MAAM,QAAQ,EAAE,MAAM,IAAI;AAC1B,OAAI,MAAM,WAAW,EACnB,OAAM,IAAI,UAAU,cAAc,iBAAiB;GAGrD,MAAM,kBAAkB,SAAS,MAAM,IAAI,GAAG;AAC9C,OAAI,MAAM,gBAAgB,CACxB,OAAM,IAAI,UAAU,cAAc,iBAAiB;AAGrD,OAAI,MAAM,OAAO,KACf,OAAM,IAAI,UAAU,cAAc,iBAAiB;GAGrD,MAAM,cAAc,SAAS,MAAM,IAAI,GAAG;AAC1C,OAAI,MAAM,YAAY,CACpB,OAAM,IAAI,UAAU,cAAc,iBAAiB;AAGrD,UAAO,UAAU,IAAI,iBAAiB,YAAY;;;;;EAMpD,OAAO,UAAqB;AAC1B,UAAO,UAAU,IAAI,GAAG,EAAE;;;;;EAM5B,WAAmB;AACjB,UAAO,GAAG,KAAK,iBAAiB,MAAM,KAAK;;;;;;CAO/C,IAAa,OAAb,MAAa,KAAK;EAChB,AAAiB;EACjB,AAAiB;EAEjB,AAAQ,YAAY,gBAAwB,QAAqB;AAC/D,QAAK,kBAAkB;AACvB,QAAK,UAAU;;;;;;;;;;;;;;EAejB,OAAO,IAAI,gBAAwB,QAA2B;AAC5D,OAAI,mBAAmB,EACrB,OAAM,IAAI,UAAU,cAAc,sBAAsB;AAE1D,OAAI,iBAAiB,OAAO,OAC1B,OAAM,IAAI,UAAU,cAAc,sBAAsB;AAE1D,OAAI,OAAO,SAASA,6BAClB,OAAM,IAAI,UAAU,cAAc,kBAAkB;AAEtD,UAAO,IAAI,KAAK,gBAAgB,OAAO;;;;;EAMzC,iBAAyB;AACvB,UAAO,KAAK;;;;;EAMd,SAAsB;AACpB,UAAO,KAAK;;;;;EAMd,aAAqB;AACnB,UAAO,KAAK,QAAQ;;;;;EAMtB,aAAqB;AACnB,UAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM,MAAM,EAAE,aAAa,EAAE,EAAE;;;;;;;;;CCxJpE,IAAa,YAAb,MAAuB;EACrB,AAAiB;EACjB,AAAiB;EACjB,AAAiB;EACjB,AAAiB;EACjB,AAAiB;EACjB,AAAiB;EACjB,AAAiB;EAEjB,YACE,YACA,YACA,gBACA,YACA,aACA,iBACA,OACA;AACA,QAAK,cAAc;AACnB,QAAK,cAAc;AACnB,QAAK,kBAAkB;AACvB,QAAK,cAAc;AACnB,QAAK,eAAe;AACpB,QAAK,mBAAmB;AACxB,QAAK,SAAS;;EAGhB,aAAqB;AACnB,UAAO,KAAK;;EAGd,aAAqB;AACnB,UAAO,KAAK;;EAGd,iBAAyB;AACvB,UAAO,KAAK;;EAGd,aAAqB;AACnB,UAAO,KAAK;;EAGd,cAAsB;AACpB,UAAO,KAAK;;EAGd,kBAA0B;AACxB,UAAO,KAAK;;EAGd,QAAgB;AACd,UAAO,KAAK;;;;;;;;;;;;;;CCvChB,SAAgB,aAAa,MAAY,cAAsC;AAE7E,SAAO,kBAAkB,MAAM,cADnB,IAAIC,wCAA6B,CACI;;;;;;;;;;;;;CAcnD,SAAgB,kBACd,MACA,cACA,iBACgB;AAKhB,SAJqB,eAAe,MAAM,cAAc,gBAAgB,CAE5B,KAAK,UAAU,MAAM,IAAI,eAAe,CAAC;;;;;;;;;;CAavF,SAAgB,YAAY,QAA8B;EACxD,MAAM,aAA0B,EAAE;AAElC,OAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,YAAY,iBAAiB,MAAM;AACzC,cAAW,KAAK,UAAU;;AAG5B,SAAO,cAAc,WAAW;;CAGlC,SAAS,eAAe,OAA8B;EAapD,MAAM,YAAY,MAAM,OAAO,CAAC,SAAS;EACzC,MAAM,SAAS,IAAI,WAAW,UAAU,SAAS,oBAAoB;EAErE,MAAM,KAAK,MAAM,YAAY;EAC7B,MAAM,KAAM,MAAM,gBAAgB,GAAG,IAAK;EAC1C,MAAM,KAAM,MAAM,YAAY,GAAG,IAAK;EACtC,MAAM,KAAK,MAAM,YAAY,GAAG;EAChC,MAAM,KAAM,MAAM,iBAAiB,GAAG,IAAK;EAC3C,MAAM,KAAK,MAAM,aAAa,GAAG;EAEjC,MAAM,MAAM,MAAM;EAClB,MAAM,MAAM,KAAK;AAEjB,SAAO,KAAK;AACZ,SAAO,KAAK;AACZ,SAAO,KAAM,MAAM,IAAK;AACxB,SAAO,KAAM,MAAM,IAAK;AACxB,SAAO,KAAK;AACZ,SAAO,IAAI,WAAW,oBAAoB;AAE1C,SAAO;;CAGT,SAAS,iBAAiB,QAA+B;AACvD,MAAI,OAAO,SAAS,oBAClB,OAAM,IAAI,UAAU,cAAc,mBAAmB;EAGvD,MAAM,kBAAkB,OAAO,MAAM,KAAK;EAC1C,MAAM,cAAc,OAAO,KAAK,MAAO;AAEvC,MAAI,iBAAiB,WACnB,OAAM,IAAI,UAAU,cAAc,sBAAsB;EAG1D,MAAM,aAAc,OAAO,MAAM,IAAK,OAAO;EAC7C,MAAM,aAAa,OAAO,MAAM;EAChC,MAAM,mBAAmB,OAAO,KAAK,MAAO;AAE5C,MADiB,OAAO,MAAM,MACb,EACf,OAAM,IAAI,UAAU,cAAc,yBAAyB;AAK7D,SAAO,IAAI,UACT,YACA,YACA,gBACA,YAPkB,OAAO,KAAK,IAS9B,iBARY,OAAO,IAAI,OAAO,SAAS,oBAAoB,CAAC,CAU7D;;CAGH,SAAS,eACP,MACA,cACA,iBACe;EAEf,MAAM,kBAAkB,IAAI,WAAW,EAAE;AACzC,kBAAgB,eAAe,gBAAgB;EAC/C,MAAM,aAAc,gBAAgB,MAAM,IAAK,gBAAgB;EAE/D,MAAM,eAA8B,EAAE;EAEtC,IAAI;AACJ,MAAI;AACF,gDACE,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,aAAa,SAAS,EACtB,gBACD;WACM,GAAG;AACV,OAAI,aAAaC,yBACf,OAAM,UAAU,gBAAgB,EAAE;AAEpC,SAAM;;AAGR,OAAK,IAAI,aAAa,GAAG,aAAa,KAAK,QAAQ,CAAC,QAAQ,cAAc;GACxE,MAAM,QAAQ,KAAK,QAAQ,CAAC;GAC5B,MAAM,cAAc,aAAa;GAEjC,IAAI;AACJ,OAAI;AACF,kDACE,MAAM,iBAAiB,EACvB,MAAM,aAAa,EACnB,aACA,gBACD;YACM,GAAG;AACV,QAAI,aAAaA,yBACf,OAAM,UAAU,gBAAgB,EAAE;AAEpC,UAAM;;GAGR,MAAM,mBAAgC,cAAc,KAAK,cAAc,gBAAgB;IACrF,MAAM,SAAS,OAAO,IAAI,aAAa;AACvC,WAAO,IAAI,UACT,YACA,YACA,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,aACA,MAAM,iBAAiB,EACvB,OACD;KACD;AAEF,gBAAa,KAAK,iBAAiB;;AAGrC,SAAO;;CAUT,SAAS,cAAc,QAA6B;EAClD,IAAI,aAAa;EACjB,IAAI,iBAAiB;EACrB,IAAI,aAAa;AAEjB,MAAI,OAAO,WAAW,EACpB,OAAM,IAAI,UAAU,cAAc,YAAY;EAGhD,IAAI,YAAY;EAChB,MAAM,SAAkB,EAAE;EAC1B,IAAI,YAAY;AAEhB,OAAK,IAAI,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;GACtC,MAAM,QAAQ,OAAO;AAErB,OAAI,MAAM,GAAG;AAEX,iBAAa,MAAM,YAAY;AAC/B,iBAAa,MAAM,YAAY;AAC/B,qBAAiB,MAAM,gBAAgB;AACvC,gBAAY,MAAM,OAAO,CAAC,KAAK;cAI7B,MAAM,YAAY,KAAK,cACvB,MAAM,gBAAgB,KAAK,kBAC3B,MAAM,YAAY,KAAK,cACvB,MAAM,OAAO,CAAC,KAAK,KAAK,UAExB,OAAM,IAAI,UAAU,cAAc,gBAAgB;GAKtD,IAAI,aAAa;AACjB,QAAK,MAAM,SAAS,OAClB,KAAI,MAAM,YAAY,KAAK,MAAM,YAAY;AAC3C,iBAAa;AACb,QAAI,MAAM,iBAAiB,KAAK,MAAM,gBACpC,OAAM,IAAI,UAAU,cAAc,uBAAuB;AAE3D,SAAK,MAAM,eAAe,MAAM,cAC9B,KAAI,MAAM,aAAa,KAAK,YAC1B,OAAM,IAAI,UAAU,cAAc,qBAAqB;AAG3D,QAAI,MAAM,cAAc,SAAS,MAAM,iBAAiB;AACtD,WAAM,cAAc,KAAK,MAAM,aAAa,CAAC;AAC7C,WAAM,aAAa,KAAK,MAAM,OAAO,CAAC,OAAO,CAAC;;;AAKpD,OAAI,CAAC,YAAY;IACf,MAAM,IAAW;KACf,YAAY,MAAM,YAAY;KAC9B,iBAAiB,MAAM,iBAAiB;KACxC,eAAe,CAAC,MAAM,aAAa,CAAC;KACpC,cAAc,CAAC,MAAM,OAAO,CAAC,OAAO,CAAC;KACtC;AACD,WAAO,KAAK,EAAE;AACd;;;AAKJ,MAAI,YAAY,eACd,OAAM,IAAI,UAAU,cAAc,gBAAgB;EAMpD,MAAM,gBAA0B,EAAE;EAClC,MAAM,eAA6B,EAAE;AAErC,OAAK,MAAM,SAAS,QAAQ;AAE1B,OAAI,MAAM,cAAc,SAAS,MAAM,gBACrC;AAIF,OAAI;IACF,MAAM,mBAAmB,MAAM,aAAa,KAAK,MAAM,EAAE,SAAS,CAAC;IACnE,MAAM,8CAA4B,MAAM,eAAe,iBAAiB;AACxE,kBAAc,KAAK,MAAM,WAAW;AACpC,iBAAa,KAAK,YAAY;WACxB;AAEN;;AAIF,OAAI,cAAc,WAAW,eAC3B;;AAKJ,MAAI,cAAc,SAAS,eACzB,OAAM,IAAI,UAAU,cAAc,gBAAgB;EAIpD,IAAI;AACJ,MAAI;AACF,sDAAiC,eAAe,aAAa;WACtD,GAAG;AACV,OAAI,aAAaA,yBACf,OAAM,UAAU,gBAAgB,EAAE;AAEpC,SAAM;;AAGR,SAAO,OAAO,IAAI,iBAAiB;;;;;;;;;;;;;CCjTrC,MAAa,iBAAiBC;;;;CAK9B,MAAa,iBAAiBC;;;;CAK9B,MAAa,kBAAkBC;;;;CAK/B,MAAa,mBAAmB;;;;CAKhC,MAAa,sBAAsB;;;;CAKnC,MAAa,2BAA2B,sBAAsB"}
|
package/dist/index.mjs
CHANGED
|
@@ -62,6 +62,11 @@ var SSKRError = class SSKRError extends Error {
|
|
|
62
62
|
//#endregion
|
|
63
63
|
//#region src/secret.ts
|
|
64
64
|
/**
|
|
65
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
66
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
67
|
+
*
|
|
68
|
+
*/
|
|
69
|
+
/**
|
|
65
70
|
* A secret to be split into shares.
|
|
66
71
|
*/
|
|
67
72
|
var Secret = class Secret {
|
|
@@ -128,6 +133,11 @@ var Secret = class Secret {
|
|
|
128
133
|
//#endregion
|
|
129
134
|
//#region src/spec.ts
|
|
130
135
|
/**
|
|
136
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
137
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
138
|
+
*
|
|
139
|
+
*/
|
|
140
|
+
/**
|
|
131
141
|
* A specification for a group of shares within an SSKR split.
|
|
132
142
|
*/
|
|
133
143
|
var GroupSpec = class GroupSpec {
|
|
@@ -461,6 +471,11 @@ function combineShares(shares) {
|
|
|
461
471
|
//#endregion
|
|
462
472
|
//#region src/index.ts
|
|
463
473
|
/**
|
|
474
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
475
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
476
|
+
*
|
|
477
|
+
*/
|
|
478
|
+
/**
|
|
464
479
|
* The minimum length of a secret.
|
|
465
480
|
*/
|
|
466
481
|
const MIN_SECRET_LEN = MIN_SECRET_LEN$1;
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["MAX_SHARE_COUNT","SHAMIR_MIN_SECRET_LEN","SHAMIR_MAX_SECRET_LEN","SHAMIR_MAX_SHARE_COUNT"],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/share.ts","../src/encoding.ts","../src/index.ts"],"sourcesContent":["// Ported from bc-sskr-rust/src/error.rs\n\nimport type { ShamirError } from \"@bcts/shamir\";\n\n/**\n * Error types for SSKR operations.\n */\nexport enum SSKRErrorType {\n DuplicateMemberIndex = \"DuplicateMemberIndex\",\n GroupSpecInvalid = \"GroupSpecInvalid\",\n GroupCountInvalid = \"GroupCountInvalid\",\n GroupThresholdInvalid = \"GroupThresholdInvalid\",\n MemberCountInvalid = \"MemberCountInvalid\",\n MemberThresholdInvalid = \"MemberThresholdInvalid\",\n NotEnoughGroups = \"NotEnoughGroups\",\n SecretLengthNotEven = \"SecretLengthNotEven\",\n SecretTooLong = \"SecretTooLong\",\n SecretTooShort = \"SecretTooShort\",\n ShareLengthInvalid = \"ShareLengthInvalid\",\n ShareReservedBitsInvalid = \"ShareReservedBitsInvalid\",\n SharesEmpty = \"SharesEmpty\",\n ShareSetInvalid = \"ShareSetInvalid\",\n ShamirError = \"ShamirError\",\n}\n\n/**\n * Error class for SSKR operations.\n */\nexport class SSKRError extends Error {\n readonly type: SSKRErrorType;\n readonly shamirError?: ShamirError | undefined;\n\n constructor(type: SSKRErrorType, message?: string, shamirError?: ShamirError) {\n super(message ?? SSKRError.defaultMessage(type, shamirError));\n this.type = type;\n this.shamirError = shamirError;\n this.name = \"SSKRError\";\n }\n\n private static defaultMessage(type: SSKRErrorType, shamirError?: ShamirError): string {\n switch (type) {\n case SSKRErrorType.DuplicateMemberIndex:\n return \"When combining shares, the provided shares contained a duplicate member index\";\n case SSKRErrorType.GroupSpecInvalid:\n return \"Invalid group specification.\";\n case SSKRErrorType.GroupCountInvalid:\n return \"When creating a split spec, the group count is invalid\";\n case SSKRErrorType.GroupThresholdInvalid:\n return \"SSKR group threshold is invalid\";\n case SSKRErrorType.MemberCountInvalid:\n return \"SSKR member count is invalid\";\n case SSKRErrorType.MemberThresholdInvalid:\n return \"SSKR member threshold is invalid\";\n case SSKRErrorType.NotEnoughGroups:\n return \"SSKR shares did not contain enough groups\";\n case SSKRErrorType.SecretLengthNotEven:\n return \"SSKR secret is not of even length\";\n case SSKRErrorType.SecretTooLong:\n return \"SSKR secret is too long\";\n case SSKRErrorType.SecretTooShort:\n return \"SSKR secret is too short\";\n case SSKRErrorType.ShareLengthInvalid:\n return \"SSKR shares did not contain enough serialized bytes\";\n case SSKRErrorType.ShareReservedBitsInvalid:\n return \"SSKR shares contained invalid reserved bits\";\n case SSKRErrorType.SharesEmpty:\n return \"SSKR shares were empty\";\n case SSKRErrorType.ShareSetInvalid:\n return \"SSKR shares were invalid\";\n case SSKRErrorType.ShamirError:\n return shamirError != null\n ? `SSKR Shamir error: ${shamirError.message}`\n : \"SSKR Shamir error\";\n }\n }\n\n static fromShamirError(error: ShamirError): SSKRError {\n return new SSKRError(SSKRErrorType.ShamirError, undefined, error);\n }\n}\n\nexport type SSKRResult<T> = T;\n","// Ported from bc-sskr-rust/src/secret.rs\n\nimport { MIN_SECRET_LEN, MAX_SECRET_LEN } from \"./index.js\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A secret to be split into shares.\n */\nexport class Secret {\n private readonly data: Uint8Array;\n\n private constructor(data: Uint8Array) {\n this.data = data;\n }\n\n /**\n * Creates a new Secret instance with the given data.\n *\n * @param data - The secret data to be split into shares.\n * @returns A new Secret instance.\n * @throws SSKRError if the length of the secret is less than\n * MIN_SECRET_LEN, greater than MAX_SECRET_LEN, or not even.\n */\n static new(data: Uint8Array | string): Secret {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const len = bytes.length;\n\n if (len < MIN_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooShort);\n }\n if (len > MAX_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooLong);\n }\n if ((len & 1) !== 0) {\n throw new SSKRError(SSKRErrorType.SecretLengthNotEven);\n }\n\n return new Secret(new Uint8Array(bytes));\n }\n\n /**\n * Returns the length of the secret.\n */\n len(): number {\n return this.data.length;\n }\n\n /**\n * Returns true if the secret is empty.\n */\n isEmpty(): boolean {\n return this.len() === 0;\n }\n\n /**\n * Returns a reference to the secret data.\n */\n getData(): Uint8Array {\n return this.data;\n }\n\n /**\n * Returns the secret data as a Uint8Array.\n */\n asRef(): Uint8Array {\n return this.data;\n }\n\n /**\n * Check equality with another Secret.\n */\n equals(other: Secret): boolean {\n if (this.data.length !== other.data.length) {\n return false;\n }\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i] !== other.data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Clone the secret.\n */\n clone(): Secret {\n return new Secret(new Uint8Array(this.data));\n }\n}\n","// Ported from bc-sskr-rust/src/spec.rs\n\nimport { MAX_SHARE_COUNT } from \"@bcts/shamir\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A specification for a group of shares within an SSKR split.\n */\nexport class GroupSpec {\n private readonly _memberThreshold: number;\n private readonly _memberCount: number;\n\n private constructor(memberThreshold: number, memberCount: number) {\n this._memberThreshold = memberThreshold;\n this._memberCount = memberCount;\n }\n\n /**\n * Creates a new GroupSpec instance with the given member threshold and count.\n *\n * @param memberThreshold - The minimum number of member shares required to\n * reconstruct the secret within the group.\n * @param memberCount - The total number of member shares in the group.\n * @returns A new GroupSpec instance.\n * @throws SSKRError if the member count is zero, if the member count is\n * greater than the maximum share count, or if the member threshold is\n * greater than the member count.\n */\n static new(memberThreshold: number, memberCount: number): GroupSpec {\n if (memberCount === 0) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberCount > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberThreshold > memberCount) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n return new GroupSpec(memberThreshold, memberCount);\n }\n\n /**\n * Returns the member share threshold for this group.\n */\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n /**\n * Returns the number of member shares in this group.\n */\n memberCount(): number {\n return this._memberCount;\n }\n\n /**\n * Parses a group specification from a string.\n * Format: \"M-of-N\" where M is the threshold and N is the count.\n */\n static parse(s: string): GroupSpec {\n const parts = s.split(\"-\");\n if (parts.length !== 3) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberThreshold = parseInt(parts[0], 10);\n if (isNaN(memberThreshold)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n if (parts[1] !== \"of\") {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberCount = parseInt(parts[2], 10);\n if (isNaN(memberCount)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n return GroupSpec.new(memberThreshold, memberCount);\n }\n\n /**\n * Creates a default GroupSpec (1-of-1).\n */\n static default(): GroupSpec {\n return GroupSpec.new(1, 1);\n }\n\n /**\n * Returns a string representation of the group spec.\n */\n toString(): string {\n return `${this._memberThreshold}-of-${this._memberCount}`;\n }\n}\n\n/**\n * A specification for an SSKR split.\n */\nexport class Spec {\n private readonly _groupThreshold: number;\n private readonly _groups: GroupSpec[];\n\n private constructor(groupThreshold: number, groups: GroupSpec[]) {\n this._groupThreshold = groupThreshold;\n this._groups = groups;\n }\n\n /**\n * Creates a new Spec instance with the given group threshold and groups.\n *\n * @param groupThreshold - The minimum number of groups required to\n * reconstruct the secret.\n * @param groups - The list of GroupSpec instances that define the groups\n * and their members.\n * @returns A new Spec instance.\n * @throws SSKRError if the group threshold is zero, if the group threshold\n * is greater than the number of groups, or if the number of groups is\n * greater than the maximum share count.\n */\n static new(groupThreshold: number, groups: GroupSpec[]): Spec {\n if (groupThreshold === 0) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groupThreshold > groups.length) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groups.length > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.GroupCountInvalid);\n }\n return new Spec(groupThreshold, groups);\n }\n\n /**\n * Returns the group threshold.\n */\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n /**\n * Returns a slice of the group specifications.\n */\n groups(): GroupSpec[] {\n return this._groups;\n }\n\n /**\n * Returns the number of groups.\n */\n groupCount(): number {\n return this._groups.length;\n }\n\n /**\n * Returns the total number of shares across all groups.\n */\n shareCount(): number {\n return this._groups.reduce((sum, g) => sum + g.memberCount(), 0);\n }\n}\n","// Ported from bc-sskr-rust/src/share.rs\n\nimport type { Secret } from \"./secret.js\";\n\n/**\n * A share in the SSKR scheme.\n */\nexport class SSKRShare {\n private readonly _identifier: number;\n private readonly _groupIndex: number;\n private readonly _groupThreshold: number;\n private readonly _groupCount: number;\n private readonly _memberIndex: number;\n private readonly _memberThreshold: number;\n private readonly _value: Secret;\n\n constructor(\n identifier: number,\n groupIndex: number,\n groupThreshold: number,\n groupCount: number,\n memberIndex: number,\n memberThreshold: number,\n value: Secret,\n ) {\n this._identifier = identifier;\n this._groupIndex = groupIndex;\n this._groupThreshold = groupThreshold;\n this._groupCount = groupCount;\n this._memberIndex = memberIndex;\n this._memberThreshold = memberThreshold;\n this._value = value;\n }\n\n identifier(): number {\n return this._identifier;\n }\n\n groupIndex(): number {\n return this._groupIndex;\n }\n\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n groupCount(): number {\n return this._groupCount;\n }\n\n memberIndex(): number {\n return this._memberIndex;\n }\n\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n value(): Secret {\n return this._value;\n }\n}\n","// Ported from bc-sskr-rust/src/encoding.rs\n\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\nimport { SecureRandomNumberGenerator } from \"@bcts/rand\";\nimport { splitSecret, recoverSecret, ShamirError } from \"@bcts/shamir\";\n\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\nimport { Secret } from \"./secret.js\";\nimport type { Spec } from \"./spec.js\";\nimport { SSKRShare } from \"./share.js\";\nimport { METADATA_SIZE_BYTES } from \"./index.js\";\n\n/**\n * Generates SSKR shares for the given Spec and Secret.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerate(spec: Spec, masterSecret: Secret): Uint8Array[][] {\n const rng = new SecureRandomNumberGenerator();\n return sskrGenerateUsing(spec, masterSecret, rng);\n}\n\n/**\n * Generates SSKR shares for the given Spec and Secret using the provided\n * random number generator.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @param randomGenerator - The random number generator to use for generating\n * shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerateUsing(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[][] {\n const groupsShares = generateShares(spec, masterSecret, randomGenerator);\n\n const result: Uint8Array[][] = groupsShares.map((group) => group.map(serializeShare));\n\n return result;\n}\n\n/**\n * Combines the given SSKR shares into a Secret.\n *\n * @param shares - A array of SSKR shares to be combined.\n * @returns The reconstructed Secret.\n * @throws SSKRError if the shares do not meet the necessary quorum of groups\n * and member shares within each group.\n */\nexport function sskrCombine(shares: Uint8Array[]): Secret {\n const sskrShares: SSKRShare[] = [];\n\n for (const share of shares) {\n const sskrShare = deserializeShare(share);\n sskrShares.push(sskrShare);\n }\n\n return combineShares(sskrShares);\n}\n\nfunction serializeShare(share: SSKRShare): Uint8Array {\n // pack the id, group and member data into 5 bytes:\n // 76543210 76543210 76543210\n // 76543210 76543210\n // ----------------====----====----====----\n // identifier: 16\n // group-threshold: 4\n // group-count: 4\n // group-index: 4\n // member-threshold: 4\n // reserved (MUST be zero): 4\n // member-index: 4\n\n const valueData = share.value().getData();\n const result = new Uint8Array(valueData.length + METADATA_SIZE_BYTES);\n\n const id = share.identifier();\n const gt = (share.groupThreshold() - 1) & 0xf;\n const gc = (share.groupCount() - 1) & 0xf;\n const gi = share.groupIndex() & 0xf;\n const mt = (share.memberThreshold() - 1) & 0xf;\n const mi = share.memberIndex() & 0xf;\n\n const id1 = id >> 8;\n const id2 = id & 0xff;\n\n result[0] = id1;\n result[1] = id2;\n result[2] = (gt << 4) | gc;\n result[3] = (gi << 4) | mt;\n result[4] = mi;\n result.set(valueData, METADATA_SIZE_BYTES);\n\n return result;\n}\n\nfunction deserializeShare(source: Uint8Array): SSKRShare {\n if (source.length < METADATA_SIZE_BYTES) {\n throw new SSKRError(SSKRErrorType.ShareLengthInvalid);\n }\n\n const groupThreshold = (source[2] >> 4) + 1;\n const groupCount = (source[2] & 0xf) + 1;\n\n if (groupThreshold > groupCount) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n\n const identifier = (source[0] << 8) | source[1];\n const groupIndex = source[3] >> 4;\n const memberThreshold = (source[3] & 0xf) + 1;\n const reserved = source[4] >> 4;\n if (reserved !== 0) {\n throw new SSKRError(SSKRErrorType.ShareReservedBitsInvalid);\n }\n const memberIndex = source[4] & 0xf;\n const value = Secret.new(source.subarray(METADATA_SIZE_BYTES));\n\n return new SSKRShare(\n identifier,\n groupIndex,\n groupThreshold,\n groupCount,\n memberIndex,\n memberThreshold,\n value,\n );\n}\n\nfunction generateShares(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): SSKRShare[][] {\n // assign a random identifier\n const identifierBytes = new Uint8Array(2);\n randomGenerator.fillRandomData(identifierBytes);\n const identifier = (identifierBytes[0] << 8) | identifierBytes[1];\n\n const groupsShares: SSKRShare[][] = [];\n\n let groupSecrets: Uint8Array[];\n try {\n groupSecrets = splitSecret(\n spec.groupThreshold(),\n spec.groupCount(),\n masterSecret.getData(),\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n for (let groupIndex = 0; groupIndex < spec.groups().length; groupIndex++) {\n const group = spec.groups()[groupIndex];\n const groupSecret = groupSecrets[groupIndex];\n\n let memberSecrets: Uint8Array[];\n try {\n memberSecrets = splitSecret(\n group.memberThreshold(),\n group.memberCount(),\n groupSecret,\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n const memberSSKRShares: SSKRShare[] = memberSecrets.map((memberSecret, memberIndex) => {\n const secret = Secret.new(memberSecret);\n return new SSKRShare(\n identifier,\n groupIndex,\n spec.groupThreshold(),\n spec.groupCount(),\n memberIndex,\n group.memberThreshold(),\n secret,\n );\n });\n\n groupsShares.push(memberSSKRShares);\n }\n\n return groupsShares;\n}\n\ninterface Group {\n groupIndex: number;\n memberThreshold: number;\n memberIndexes: number[];\n memberShares: Secret[];\n}\n\nfunction combineShares(shares: SSKRShare[]): Secret {\n let identifier = 0;\n let groupThreshold = 0;\n let groupCount = 0;\n\n if (shares.length === 0) {\n throw new SSKRError(SSKRErrorType.SharesEmpty);\n }\n\n let nextGroup = 0;\n const groups: Group[] = [];\n let secretLen = 0;\n\n for (let i = 0; i < shares.length; i++) {\n const share = shares[i];\n\n if (i === 0) {\n // on the first one, establish expected values for common metadata\n identifier = share.identifier();\n groupCount = share.groupCount();\n groupThreshold = share.groupThreshold();\n secretLen = share.value().len();\n } else {\n // on subsequent shares, check that common metadata matches\n if (\n share.identifier() !== identifier ||\n share.groupThreshold() !== groupThreshold ||\n share.groupCount() !== groupCount ||\n share.value().len() !== secretLen\n ) {\n throw new SSKRError(SSKRErrorType.ShareSetInvalid);\n }\n }\n\n // sort shares into member groups\n let groupFound = false;\n for (const group of groups) {\n if (share.groupIndex() === group.groupIndex) {\n groupFound = true;\n if (share.memberThreshold() !== group.memberThreshold) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n for (const memberIndex of group.memberIndexes) {\n if (share.memberIndex() === memberIndex) {\n throw new SSKRError(SSKRErrorType.DuplicateMemberIndex);\n }\n }\n if (group.memberIndexes.length < group.memberThreshold) {\n group.memberIndexes.push(share.memberIndex());\n group.memberShares.push(share.value().clone());\n }\n }\n }\n\n if (!groupFound) {\n const g: Group = {\n groupIndex: share.groupIndex(),\n memberThreshold: share.memberThreshold(),\n memberIndexes: [share.memberIndex()],\n memberShares: [share.value().clone()],\n };\n groups.push(g);\n nextGroup++;\n }\n }\n\n // Check that we have enough groups to recover the master secret\n if (nextGroup < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Here, all of the shares are unpacked into member groups. Now we go\n // through each group and recover the group secret, and then use the\n // result to recover the master secret\n const masterIndexes: number[] = [];\n const masterShares: Uint8Array[] = [];\n\n for (const group of groups) {\n // Only attempt to recover the group secret if we have enough shares\n if (group.memberIndexes.length < group.memberThreshold) {\n continue;\n }\n\n // Recover the group secret\n try {\n const memberSharesData = group.memberShares.map((s) => s.getData());\n const groupSecret = recoverSecret(group.memberIndexes, memberSharesData);\n masterIndexes.push(group.groupIndex);\n masterShares.push(groupSecret);\n } catch {\n // If we can't recover this group, just skip it\n continue;\n }\n\n // Stop if we have enough groups to recover the master secret\n if (masterIndexes.length === groupThreshold) {\n break;\n }\n }\n\n // If we don't have enough groups to recover the master secret, return an error\n if (masterIndexes.length < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Recover the master secret\n let masterSecretData: Uint8Array;\n try {\n masterSecretData = recoverSecret(masterIndexes, masterShares);\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n return Secret.new(masterSecretData);\n}\n","// Blockchain Commons Sharded Secret Key Reconstruction (SSKR)\n// Ported from bc-sskr-rust\n//\n// Sharded Secret Key Reconstruction (SSKR) is a protocol for splitting a\n// secret into a set of shares across one or more groups, such that the\n// secret can be reconstructed from any combination of shares totaling or\n// exceeding a threshold number of shares within each group and across all\n// groups. SSKR is a generalization of Shamir's Secret Sharing (SSS) that\n// allows for multiple groups and multiple thresholds.\n\nimport {\n MIN_SECRET_LEN as SHAMIR_MIN_SECRET_LEN,\n MAX_SECRET_LEN as SHAMIR_MAX_SECRET_LEN,\n MAX_SHARE_COUNT as SHAMIR_MAX_SHARE_COUNT,\n} from \"@bcts/shamir\";\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = SHAMIR_MIN_SECRET_LEN;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = SHAMIR_MAX_SECRET_LEN;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = SHAMIR_MAX_SHARE_COUNT;\n\n/**\n * The maximum number of groups in a split.\n */\nexport const MAX_GROUPS_COUNT = MAX_SHARE_COUNT;\n\n/**\n * The number of bytes used to encode the metadata for a share.\n */\nexport const METADATA_SIZE_BYTES = 5;\n\n/**\n * The minimum number of bytes required to encode a share.\n */\nexport const MIN_SERIALIZE_SIZE_BYTES = METADATA_SIZE_BYTES + MIN_SECRET_LEN;\n\n// Error types\nexport { SSKRError, SSKRErrorType, type SSKRResult } from \"./error.js\";\n\n// Secret\nexport { Secret } from \"./secret.js\";\n\n// Specifications\nexport { GroupSpec, Spec } from \"./spec.js\";\n\n// Encoding/Decoding\nexport { sskrGenerate, sskrGenerateUsing, sskrCombine } from \"./encoding.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["MAX_SHARE_COUNT","SHAMIR_MIN_SECRET_LEN","SHAMIR_MAX_SECRET_LEN","SHAMIR_MAX_SHARE_COUNT"],"sources":["../src/error.ts","../src/secret.ts","../src/spec.ts","../src/share.ts","../src/encoding.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-sskr-rust/src/error.rs\n\nimport type { ShamirError } from \"@bcts/shamir\";\n\n/**\n * Error types for SSKR operations.\n */\nexport enum SSKRErrorType {\n DuplicateMemberIndex = \"DuplicateMemberIndex\",\n GroupSpecInvalid = \"GroupSpecInvalid\",\n GroupCountInvalid = \"GroupCountInvalid\",\n GroupThresholdInvalid = \"GroupThresholdInvalid\",\n MemberCountInvalid = \"MemberCountInvalid\",\n MemberThresholdInvalid = \"MemberThresholdInvalid\",\n NotEnoughGroups = \"NotEnoughGroups\",\n SecretLengthNotEven = \"SecretLengthNotEven\",\n SecretTooLong = \"SecretTooLong\",\n SecretTooShort = \"SecretTooShort\",\n ShareLengthInvalid = \"ShareLengthInvalid\",\n ShareReservedBitsInvalid = \"ShareReservedBitsInvalid\",\n SharesEmpty = \"SharesEmpty\",\n ShareSetInvalid = \"ShareSetInvalid\",\n ShamirError = \"ShamirError\",\n}\n\n/**\n * Error class for SSKR operations.\n */\nexport class SSKRError extends Error {\n readonly type: SSKRErrorType;\n readonly shamirError?: ShamirError | undefined;\n\n constructor(type: SSKRErrorType, message?: string, shamirError?: ShamirError) {\n super(message ?? SSKRError.defaultMessage(type, shamirError));\n this.type = type;\n this.shamirError = shamirError;\n this.name = \"SSKRError\";\n }\n\n private static defaultMessage(type: SSKRErrorType, shamirError?: ShamirError): string {\n switch (type) {\n case SSKRErrorType.DuplicateMemberIndex:\n return \"When combining shares, the provided shares contained a duplicate member index\";\n case SSKRErrorType.GroupSpecInvalid:\n return \"Invalid group specification.\";\n case SSKRErrorType.GroupCountInvalid:\n return \"When creating a split spec, the group count is invalid\";\n case SSKRErrorType.GroupThresholdInvalid:\n return \"SSKR group threshold is invalid\";\n case SSKRErrorType.MemberCountInvalid:\n return \"SSKR member count is invalid\";\n case SSKRErrorType.MemberThresholdInvalid:\n return \"SSKR member threshold is invalid\";\n case SSKRErrorType.NotEnoughGroups:\n return \"SSKR shares did not contain enough groups\";\n case SSKRErrorType.SecretLengthNotEven:\n return \"SSKR secret is not of even length\";\n case SSKRErrorType.SecretTooLong:\n return \"SSKR secret is too long\";\n case SSKRErrorType.SecretTooShort:\n return \"SSKR secret is too short\";\n case SSKRErrorType.ShareLengthInvalid:\n return \"SSKR shares did not contain enough serialized bytes\";\n case SSKRErrorType.ShareReservedBitsInvalid:\n return \"SSKR shares contained invalid reserved bits\";\n case SSKRErrorType.SharesEmpty:\n return \"SSKR shares were empty\";\n case SSKRErrorType.ShareSetInvalid:\n return \"SSKR shares were invalid\";\n case SSKRErrorType.ShamirError:\n return shamirError != null\n ? `SSKR Shamir error: ${shamirError.message}`\n : \"SSKR Shamir error\";\n }\n }\n\n static fromShamirError(error: ShamirError): SSKRError {\n return new SSKRError(SSKRErrorType.ShamirError, undefined, error);\n }\n}\n\nexport type SSKRResult<T> = T;\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/secret.rs\n\nimport { MIN_SECRET_LEN, MAX_SECRET_LEN } from \"./index.js\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A secret to be split into shares.\n */\nexport class Secret {\n private readonly data: Uint8Array;\n\n private constructor(data: Uint8Array) {\n this.data = data;\n }\n\n /**\n * Creates a new Secret instance with the given data.\n *\n * @param data - The secret data to be split into shares.\n * @returns A new Secret instance.\n * @throws SSKRError if the length of the secret is less than\n * MIN_SECRET_LEN, greater than MAX_SECRET_LEN, or not even.\n */\n static new(data: Uint8Array | string): Secret {\n const bytes = typeof data === \"string\" ? new TextEncoder().encode(data) : data;\n const len = bytes.length;\n\n if (len < MIN_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooShort);\n }\n if (len > MAX_SECRET_LEN) {\n throw new SSKRError(SSKRErrorType.SecretTooLong);\n }\n if ((len & 1) !== 0) {\n throw new SSKRError(SSKRErrorType.SecretLengthNotEven);\n }\n\n return new Secret(new Uint8Array(bytes));\n }\n\n /**\n * Returns the length of the secret.\n */\n len(): number {\n return this.data.length;\n }\n\n /**\n * Returns true if the secret is empty.\n */\n isEmpty(): boolean {\n return this.len() === 0;\n }\n\n /**\n * Returns a reference to the secret data.\n */\n getData(): Uint8Array {\n return this.data;\n }\n\n /**\n * Returns the secret data as a Uint8Array.\n */\n asRef(): Uint8Array {\n return this.data;\n }\n\n /**\n * Check equality with another Secret.\n */\n equals(other: Secret): boolean {\n if (this.data.length !== other.data.length) {\n return false;\n }\n for (let i = 0; i < this.data.length; i++) {\n if (this.data[i] !== other.data[i]) {\n return false;\n }\n }\n return true;\n }\n\n /**\n * Clone the secret.\n */\n clone(): Secret {\n return new Secret(new Uint8Array(this.data));\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/spec.rs\n\nimport { MAX_SHARE_COUNT } from \"@bcts/shamir\";\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\n\n/**\n * A specification for a group of shares within an SSKR split.\n */\nexport class GroupSpec {\n private readonly _memberThreshold: number;\n private readonly _memberCount: number;\n\n private constructor(memberThreshold: number, memberCount: number) {\n this._memberThreshold = memberThreshold;\n this._memberCount = memberCount;\n }\n\n /**\n * Creates a new GroupSpec instance with the given member threshold and count.\n *\n * @param memberThreshold - The minimum number of member shares required to\n * reconstruct the secret within the group.\n * @param memberCount - The total number of member shares in the group.\n * @returns A new GroupSpec instance.\n * @throws SSKRError if the member count is zero, if the member count is\n * greater than the maximum share count, or if the member threshold is\n * greater than the member count.\n */\n static new(memberThreshold: number, memberCount: number): GroupSpec {\n if (memberCount === 0) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberCount > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.MemberCountInvalid);\n }\n if (memberThreshold > memberCount) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n return new GroupSpec(memberThreshold, memberCount);\n }\n\n /**\n * Returns the member share threshold for this group.\n */\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n /**\n * Returns the number of member shares in this group.\n */\n memberCount(): number {\n return this._memberCount;\n }\n\n /**\n * Parses a group specification from a string.\n * Format: \"M-of-N\" where M is the threshold and N is the count.\n */\n static parse(s: string): GroupSpec {\n const parts = s.split(\"-\");\n if (parts.length !== 3) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberThreshold = parseInt(parts[0], 10);\n if (isNaN(memberThreshold)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n if (parts[1] !== \"of\") {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n const memberCount = parseInt(parts[2], 10);\n if (isNaN(memberCount)) {\n throw new SSKRError(SSKRErrorType.GroupSpecInvalid);\n }\n\n return GroupSpec.new(memberThreshold, memberCount);\n }\n\n /**\n * Creates a default GroupSpec (1-of-1).\n */\n static default(): GroupSpec {\n return GroupSpec.new(1, 1);\n }\n\n /**\n * Returns a string representation of the group spec.\n */\n toString(): string {\n return `${this._memberThreshold}-of-${this._memberCount}`;\n }\n}\n\n/**\n * A specification for an SSKR split.\n */\nexport class Spec {\n private readonly _groupThreshold: number;\n private readonly _groups: GroupSpec[];\n\n private constructor(groupThreshold: number, groups: GroupSpec[]) {\n this._groupThreshold = groupThreshold;\n this._groups = groups;\n }\n\n /**\n * Creates a new Spec instance with the given group threshold and groups.\n *\n * @param groupThreshold - The minimum number of groups required to\n * reconstruct the secret.\n * @param groups - The list of GroupSpec instances that define the groups\n * and their members.\n * @returns A new Spec instance.\n * @throws SSKRError if the group threshold is zero, if the group threshold\n * is greater than the number of groups, or if the number of groups is\n * greater than the maximum share count.\n */\n static new(groupThreshold: number, groups: GroupSpec[]): Spec {\n if (groupThreshold === 0) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groupThreshold > groups.length) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n if (groups.length > MAX_SHARE_COUNT) {\n throw new SSKRError(SSKRErrorType.GroupCountInvalid);\n }\n return new Spec(groupThreshold, groups);\n }\n\n /**\n * Returns the group threshold.\n */\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n /**\n * Returns a slice of the group specifications.\n */\n groups(): GroupSpec[] {\n return this._groups;\n }\n\n /**\n * Returns the number of groups.\n */\n groupCount(): number {\n return this._groups.length;\n }\n\n /**\n * Returns the total number of shares across all groups.\n */\n shareCount(): number {\n return this._groups.reduce((sum, g) => sum + g.memberCount(), 0);\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/share.rs\n\nimport type { Secret } from \"./secret.js\";\n\n/**\n * A share in the SSKR scheme.\n */\nexport class SSKRShare {\n private readonly _identifier: number;\n private readonly _groupIndex: number;\n private readonly _groupThreshold: number;\n private readonly _groupCount: number;\n private readonly _memberIndex: number;\n private readonly _memberThreshold: number;\n private readonly _value: Secret;\n\n constructor(\n identifier: number,\n groupIndex: number,\n groupThreshold: number,\n groupCount: number,\n memberIndex: number,\n memberThreshold: number,\n value: Secret,\n ) {\n this._identifier = identifier;\n this._groupIndex = groupIndex;\n this._groupThreshold = groupThreshold;\n this._groupCount = groupCount;\n this._memberIndex = memberIndex;\n this._memberThreshold = memberThreshold;\n this._value = value;\n }\n\n identifier(): number {\n return this._identifier;\n }\n\n groupIndex(): number {\n return this._groupIndex;\n }\n\n groupThreshold(): number {\n return this._groupThreshold;\n }\n\n groupCount(): number {\n return this._groupCount;\n }\n\n memberIndex(): number {\n return this._memberIndex;\n }\n\n memberThreshold(): number {\n return this._memberThreshold;\n }\n\n value(): Secret {\n return this._value;\n }\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Ported from bc-sskr-rust/src/encoding.rs\n\nimport type { RandomNumberGenerator } from \"@bcts/rand\";\nimport { SecureRandomNumberGenerator } from \"@bcts/rand\";\nimport { splitSecret, recoverSecret, ShamirError } from \"@bcts/shamir\";\n\nimport { SSKRError, SSKRErrorType } from \"./error.js\";\nimport { Secret } from \"./secret.js\";\nimport type { Spec } from \"./spec.js\";\nimport { SSKRShare } from \"./share.js\";\nimport { METADATA_SIZE_BYTES } from \"./index.js\";\n\n/**\n * Generates SSKR shares for the given Spec and Secret.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerate(spec: Spec, masterSecret: Secret): Uint8Array[][] {\n const rng = new SecureRandomNumberGenerator();\n return sskrGenerateUsing(spec, masterSecret, rng);\n}\n\n/**\n * Generates SSKR shares for the given Spec and Secret using the provided\n * random number generator.\n *\n * @param spec - The Spec instance that defines the group and member thresholds.\n * @param masterSecret - The Secret instance to be split into shares.\n * @param randomGenerator - The random number generator to use for generating\n * shares.\n * @returns A vector of groups, each containing a vector of shares,\n * each of which is a Uint8Array.\n */\nexport function sskrGenerateUsing(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): Uint8Array[][] {\n const groupsShares = generateShares(spec, masterSecret, randomGenerator);\n\n const result: Uint8Array[][] = groupsShares.map((group) => group.map(serializeShare));\n\n return result;\n}\n\n/**\n * Combines the given SSKR shares into a Secret.\n *\n * @param shares - A array of SSKR shares to be combined.\n * @returns The reconstructed Secret.\n * @throws SSKRError if the shares do not meet the necessary quorum of groups\n * and member shares within each group.\n */\nexport function sskrCombine(shares: Uint8Array[]): Secret {\n const sskrShares: SSKRShare[] = [];\n\n for (const share of shares) {\n const sskrShare = deserializeShare(share);\n sskrShares.push(sskrShare);\n }\n\n return combineShares(sskrShares);\n}\n\nfunction serializeShare(share: SSKRShare): Uint8Array {\n // pack the id, group and member data into 5 bytes:\n // 76543210 76543210 76543210\n // 76543210 76543210\n // ----------------====----====----====----\n // identifier: 16\n // group-threshold: 4\n // group-count: 4\n // group-index: 4\n // member-threshold: 4\n // reserved (MUST be zero): 4\n // member-index: 4\n\n const valueData = share.value().getData();\n const result = new Uint8Array(valueData.length + METADATA_SIZE_BYTES);\n\n const id = share.identifier();\n const gt = (share.groupThreshold() - 1) & 0xf;\n const gc = (share.groupCount() - 1) & 0xf;\n const gi = share.groupIndex() & 0xf;\n const mt = (share.memberThreshold() - 1) & 0xf;\n const mi = share.memberIndex() & 0xf;\n\n const id1 = id >> 8;\n const id2 = id & 0xff;\n\n result[0] = id1;\n result[1] = id2;\n result[2] = (gt << 4) | gc;\n result[3] = (gi << 4) | mt;\n result[4] = mi;\n result.set(valueData, METADATA_SIZE_BYTES);\n\n return result;\n}\n\nfunction deserializeShare(source: Uint8Array): SSKRShare {\n if (source.length < METADATA_SIZE_BYTES) {\n throw new SSKRError(SSKRErrorType.ShareLengthInvalid);\n }\n\n const groupThreshold = (source[2] >> 4) + 1;\n const groupCount = (source[2] & 0xf) + 1;\n\n if (groupThreshold > groupCount) {\n throw new SSKRError(SSKRErrorType.GroupThresholdInvalid);\n }\n\n const identifier = (source[0] << 8) | source[1];\n const groupIndex = source[3] >> 4;\n const memberThreshold = (source[3] & 0xf) + 1;\n const reserved = source[4] >> 4;\n if (reserved !== 0) {\n throw new SSKRError(SSKRErrorType.ShareReservedBitsInvalid);\n }\n const memberIndex = source[4] & 0xf;\n const value = Secret.new(source.subarray(METADATA_SIZE_BYTES));\n\n return new SSKRShare(\n identifier,\n groupIndex,\n groupThreshold,\n groupCount,\n memberIndex,\n memberThreshold,\n value,\n );\n}\n\nfunction generateShares(\n spec: Spec,\n masterSecret: Secret,\n randomGenerator: RandomNumberGenerator,\n): SSKRShare[][] {\n // assign a random identifier\n const identifierBytes = new Uint8Array(2);\n randomGenerator.fillRandomData(identifierBytes);\n const identifier = (identifierBytes[0] << 8) | identifierBytes[1];\n\n const groupsShares: SSKRShare[][] = [];\n\n let groupSecrets: Uint8Array[];\n try {\n groupSecrets = splitSecret(\n spec.groupThreshold(),\n spec.groupCount(),\n masterSecret.getData(),\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n for (let groupIndex = 0; groupIndex < spec.groups().length; groupIndex++) {\n const group = spec.groups()[groupIndex];\n const groupSecret = groupSecrets[groupIndex];\n\n let memberSecrets: Uint8Array[];\n try {\n memberSecrets = splitSecret(\n group.memberThreshold(),\n group.memberCount(),\n groupSecret,\n randomGenerator,\n );\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n const memberSSKRShares: SSKRShare[] = memberSecrets.map((memberSecret, memberIndex) => {\n const secret = Secret.new(memberSecret);\n return new SSKRShare(\n identifier,\n groupIndex,\n spec.groupThreshold(),\n spec.groupCount(),\n memberIndex,\n group.memberThreshold(),\n secret,\n );\n });\n\n groupsShares.push(memberSSKRShares);\n }\n\n return groupsShares;\n}\n\ninterface Group {\n groupIndex: number;\n memberThreshold: number;\n memberIndexes: number[];\n memberShares: Secret[];\n}\n\nfunction combineShares(shares: SSKRShare[]): Secret {\n let identifier = 0;\n let groupThreshold = 0;\n let groupCount = 0;\n\n if (shares.length === 0) {\n throw new SSKRError(SSKRErrorType.SharesEmpty);\n }\n\n let nextGroup = 0;\n const groups: Group[] = [];\n let secretLen = 0;\n\n for (let i = 0; i < shares.length; i++) {\n const share = shares[i];\n\n if (i === 0) {\n // on the first one, establish expected values for common metadata\n identifier = share.identifier();\n groupCount = share.groupCount();\n groupThreshold = share.groupThreshold();\n secretLen = share.value().len();\n } else {\n // on subsequent shares, check that common metadata matches\n if (\n share.identifier() !== identifier ||\n share.groupThreshold() !== groupThreshold ||\n share.groupCount() !== groupCount ||\n share.value().len() !== secretLen\n ) {\n throw new SSKRError(SSKRErrorType.ShareSetInvalid);\n }\n }\n\n // sort shares into member groups\n let groupFound = false;\n for (const group of groups) {\n if (share.groupIndex() === group.groupIndex) {\n groupFound = true;\n if (share.memberThreshold() !== group.memberThreshold) {\n throw new SSKRError(SSKRErrorType.MemberThresholdInvalid);\n }\n for (const memberIndex of group.memberIndexes) {\n if (share.memberIndex() === memberIndex) {\n throw new SSKRError(SSKRErrorType.DuplicateMemberIndex);\n }\n }\n if (group.memberIndexes.length < group.memberThreshold) {\n group.memberIndexes.push(share.memberIndex());\n group.memberShares.push(share.value().clone());\n }\n }\n }\n\n if (!groupFound) {\n const g: Group = {\n groupIndex: share.groupIndex(),\n memberThreshold: share.memberThreshold(),\n memberIndexes: [share.memberIndex()],\n memberShares: [share.value().clone()],\n };\n groups.push(g);\n nextGroup++;\n }\n }\n\n // Check that we have enough groups to recover the master secret\n if (nextGroup < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Here, all of the shares are unpacked into member groups. Now we go\n // through each group and recover the group secret, and then use the\n // result to recover the master secret\n const masterIndexes: number[] = [];\n const masterShares: Uint8Array[] = [];\n\n for (const group of groups) {\n // Only attempt to recover the group secret if we have enough shares\n if (group.memberIndexes.length < group.memberThreshold) {\n continue;\n }\n\n // Recover the group secret\n try {\n const memberSharesData = group.memberShares.map((s) => s.getData());\n const groupSecret = recoverSecret(group.memberIndexes, memberSharesData);\n masterIndexes.push(group.groupIndex);\n masterShares.push(groupSecret);\n } catch {\n // If we can't recover this group, just skip it\n continue;\n }\n\n // Stop if we have enough groups to recover the master secret\n if (masterIndexes.length === groupThreshold) {\n break;\n }\n }\n\n // If we don't have enough groups to recover the master secret, return an error\n if (masterIndexes.length < groupThreshold) {\n throw new SSKRError(SSKRErrorType.NotEnoughGroups);\n }\n\n // Recover the master secret\n let masterSecretData: Uint8Array;\n try {\n masterSecretData = recoverSecret(masterIndexes, masterShares);\n } catch (e) {\n if (e instanceof ShamirError) {\n throw SSKRError.fromShamirError(e);\n }\n throw e;\n }\n\n return Secret.new(masterSecretData);\n}\n","/**\n * Copyright © 2023-2026 Blockchain Commons, LLC\n * Copyright © 2025-2026 Parity Technologies\n *\n */\n\n// Blockchain Commons Sharded Secret Key Reconstruction (SSKR)\n// Ported from bc-sskr-rust\n//\n// Sharded Secret Key Reconstruction (SSKR) is a protocol for splitting a\n// secret into a set of shares across one or more groups, such that the\n// secret can be reconstructed from any combination of shares totaling or\n// exceeding a threshold number of shares within each group and across all\n// groups. SSKR is a generalization of Shamir's Secret Sharing (SSS) that\n// allows for multiple groups and multiple thresholds.\n\nimport {\n MIN_SECRET_LEN as SHAMIR_MIN_SECRET_LEN,\n MAX_SECRET_LEN as SHAMIR_MAX_SECRET_LEN,\n MAX_SHARE_COUNT as SHAMIR_MAX_SHARE_COUNT,\n} from \"@bcts/shamir\";\n\n/**\n * The minimum length of a secret.\n */\nexport const MIN_SECRET_LEN = SHAMIR_MIN_SECRET_LEN;\n\n/**\n * The maximum length of a secret.\n */\nexport const MAX_SECRET_LEN = SHAMIR_MAX_SECRET_LEN;\n\n/**\n * The maximum number of shares that can be generated from a secret.\n */\nexport const MAX_SHARE_COUNT = SHAMIR_MAX_SHARE_COUNT;\n\n/**\n * The maximum number of groups in a split.\n */\nexport const MAX_GROUPS_COUNT = MAX_SHARE_COUNT;\n\n/**\n * The number of bytes used to encode the metadata for a share.\n */\nexport const METADATA_SIZE_BYTES = 5;\n\n/**\n * The minimum number of bytes required to encode a share.\n */\nexport const MIN_SERIALIZE_SIZE_BYTES = METADATA_SIZE_BYTES + MIN_SECRET_LEN;\n\n// Error types\nexport { SSKRError, SSKRErrorType, type SSKRResult } from \"./error.js\";\n\n// Secret\nexport { Secret } from \"./secret.js\";\n\n// Specifications\nexport { GroupSpec, Spec } from \"./spec.js\";\n\n// Encoding/Decoding\nexport { sskrGenerate, sskrGenerateUsing, sskrCombine } from \"./encoding.js\";\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,29 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bcts/sskr",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.21",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Blockchain Commons Sharded Secret Key Reconstruction (SSKR) for TypeScript",
|
|
6
6
|
"license": "BSD-2-Clause-Patent",
|
|
7
|
-
"
|
|
8
|
-
{
|
|
9
|
-
"name": "Leonardo Custodio",
|
|
10
|
-
"email": "leonardo.custodio@parity.io",
|
|
11
|
-
"url": "https://github.com/leonardocustodio"
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
"name": "Karim Jedda",
|
|
15
|
-
"email": "karim@parity.io",
|
|
16
|
-
"url": "https://github.com/KarimJedda"
|
|
17
|
-
}
|
|
18
|
-
],
|
|
7
|
+
"author": "Parity Technologies <admin@parity.io> (https://parity.io)",
|
|
19
8
|
"homepage": "https://bcts.dev",
|
|
20
9
|
"repository": {
|
|
21
10
|
"type": "git",
|
|
22
|
-
"url": "https://github.com/
|
|
11
|
+
"url": "https://github.com/paritytech/bcts",
|
|
23
12
|
"directory": "packages/sskr"
|
|
24
13
|
},
|
|
25
14
|
"bugs": {
|
|
26
|
-
"url": "https://github.com/
|
|
15
|
+
"url": "https://github.com/paritytech/bcts/issues"
|
|
27
16
|
},
|
|
28
17
|
"main": "dist/index.cjs",
|
|
29
18
|
"module": "dist/index.mjs",
|
|
@@ -67,18 +56,18 @@
|
|
|
67
56
|
"node": ">=18.0.0"
|
|
68
57
|
},
|
|
69
58
|
"dependencies": {
|
|
70
|
-
"@bcts/rand": "^1.0.0-alpha.
|
|
71
|
-
"@bcts/shamir": "^1.0.0-alpha.
|
|
59
|
+
"@bcts/rand": "^1.0.0-alpha.21",
|
|
60
|
+
"@bcts/shamir": "^1.0.0-alpha.21"
|
|
72
61
|
},
|
|
73
62
|
"devDependencies": {
|
|
74
63
|
"@bcts/eslint": "^0.1.0",
|
|
75
64
|
"@bcts/tsconfig": "^0.1.0",
|
|
76
|
-
"@eslint/js": "^
|
|
77
|
-
"@types/node": "^25.2
|
|
78
|
-
"eslint": "^
|
|
65
|
+
"@eslint/js": "^10.0.1",
|
|
66
|
+
"@types/node": "^25.3.2",
|
|
67
|
+
"eslint": "^10.0.2",
|
|
79
68
|
"ts-node": "^10.9.2",
|
|
80
69
|
"tsdown": "^0.20.3",
|
|
81
|
-
"typedoc": "^0.28.
|
|
70
|
+
"typedoc": "^0.28.17",
|
|
82
71
|
"typescript": "^5.9.3",
|
|
83
72
|
"vitest": "^4.0.18"
|
|
84
73
|
}
|
package/src/encoding.ts
CHANGED
package/src/error.ts
CHANGED
package/src/index.ts
CHANGED
package/src/secret.ts
CHANGED
package/src/share.ts
CHANGED