threshold-elgamal 1.0.9 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/README.md +33 -35
  2. package/dist/core/bigint.d.ts +2 -1
  3. package/dist/core/bigint.js +6 -1
  4. package/dist/core/bytes.js +4 -0
  5. package/dist/core/crypto.js +5 -0
  6. package/dist/core/errors.d.ts +50 -11
  7. package/dist/core/errors.js +50 -11
  8. package/dist/core/groups.d.ts +6 -1
  9. package/dist/core/groups.js +13 -2
  10. package/dist/core/index.d.ts +4 -0
  11. package/dist/core/index.js +4 -0
  12. package/dist/core/public.d.ts +13 -0
  13. package/dist/core/public.js +12 -0
  14. package/dist/core/random.js +4 -0
  15. package/dist/core/ristretto.d.ts +7 -0
  16. package/dist/core/ristretto.js +7 -0
  17. package/dist/core/types.d.ts +14 -6
  18. package/dist/core/validation.d.ts +45 -12
  19. package/dist/core/validation.js +52 -12
  20. package/dist/dkg/pedersen-share-codec.d.ts +12 -2
  21. package/dist/dkg/pedersen-share-codec.js +19 -2
  22. package/dist/dkg/public.d.ts +12 -0
  23. package/dist/dkg/public.js +11 -0
  24. package/dist/dkg/verification.d.ts +33 -14
  25. package/dist/dkg/verification.js +16 -12
  26. package/dist/elgamal/additive.d.ts +15 -3
  27. package/dist/elgamal/additive.js +27 -23
  28. package/dist/elgamal/bsgs.js +7 -0
  29. package/dist/elgamal/public.d.ts +11 -0
  30. package/dist/elgamal/public.js +10 -0
  31. package/dist/elgamal/types.d.ts +6 -0
  32. package/dist/index.d.ts +27 -25
  33. package/dist/index.js +20 -19
  34. package/dist/proofs/disjunctive.d.ts +11 -16
  35. package/dist/proofs/disjunctive.js +12 -17
  36. package/dist/proofs/dleq.d.ts +17 -13
  37. package/dist/proofs/dleq.js +11 -12
  38. package/dist/proofs/helpers.d.ts +1 -1
  39. package/dist/proofs/helpers.js +5 -4
  40. package/dist/proofs/nonces.js +6 -0
  41. package/dist/proofs/public.d.ts +12 -0
  42. package/dist/proofs/public.js +11 -0
  43. package/dist/proofs/schnorr.d.ts +10 -11
  44. package/dist/proofs/schnorr.js +10 -11
  45. package/dist/proofs/types.d.ts +30 -5
  46. package/dist/protocol/board-audit.d.ts +8 -3
  47. package/dist/protocol/board-audit.js +8 -2
  48. package/dist/protocol/builders.d.ts +77 -13
  49. package/dist/protocol/builders.js +83 -13
  50. package/dist/protocol/canonical-json.js +4 -0
  51. package/dist/protocol/manifest.d.ts +32 -15
  52. package/dist/protocol/manifest.js +65 -18
  53. package/dist/protocol/ordering.js +6 -0
  54. package/dist/protocol/payloads.d.ts +3 -3
  55. package/dist/protocol/payloads.js +7 -3
  56. package/dist/protocol/public.d.ts +17 -0
  57. package/dist/protocol/public.js +16 -0
  58. package/dist/protocol/score-range.d.ts +6 -0
  59. package/dist/protocol/score-range.js +24 -0
  60. package/dist/protocol/transcript.js +4 -0
  61. package/dist/protocol/types.d.ts +110 -17
  62. package/dist/protocol/verification.d.ts +14 -7
  63. package/dist/protocol/verification.js +7 -5
  64. package/dist/protocol/voting-ballot-aggregation.d.ts +10 -2
  65. package/dist/protocol/voting-ballot-aggregation.js +6 -0
  66. package/dist/protocol/voting-ballots.d.ts +3 -5
  67. package/dist/protocol/voting-ballots.js +6 -5
  68. package/dist/protocol/voting-codecs.d.ts +8 -3
  69. package/dist/protocol/voting-codecs.js +18 -2
  70. package/dist/protocol/voting-decryption.d.ts +3 -5
  71. package/dist/protocol/voting-decryption.js +7 -5
  72. package/dist/protocol/voting-shared.d.ts +2 -1
  73. package/dist/protocol/voting-shared.js +9 -2
  74. package/dist/protocol/voting-verification.d.ts +27 -30
  75. package/dist/protocol/voting-verification.js +13 -26
  76. package/dist/serialize/encoding.js +4 -0
  77. package/dist/threshold/decrypt.d.ts +13 -5
  78. package/dist/threshold/decrypt.js +20 -5
  79. package/dist/threshold/public.d.ts +11 -0
  80. package/dist/threshold/public.js +10 -0
  81. package/dist/threshold/types.d.ts +23 -4
  82. package/dist/transport/auth.d.ts +10 -16
  83. package/dist/transport/auth.js +16 -16
  84. package/dist/transport/complaints.d.ts +2 -4
  85. package/dist/transport/complaints.js +8 -4
  86. package/dist/transport/envelopes.d.ts +5 -7
  87. package/dist/transport/envelopes.js +9 -7
  88. package/dist/transport/key-agreement.d.ts +15 -23
  89. package/dist/transport/key-agreement.js +21 -23
  90. package/dist/transport/types.d.ts +16 -2
  91. package/dist/vss/feldman.d.ts +11 -1
  92. package/dist/vss/feldman.js +11 -1
  93. package/dist/vss/pedersen.d.ts +13 -0
  94. package/dist/vss/pedersen.js +13 -0
  95. package/dist/vss/public.d.ts +10 -0
  96. package/dist/vss/public.js +9 -0
  97. package/dist/vss/types.d.ts +4 -0
  98. package/package.json +43 -14
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Transport-layer types for authentication keys, X25519 envelopes, and the
3
+ * metadata that binds encrypted share delivery to one ceremony slot.
4
+ */
1
5
  import type { Brand } from '../core/types.js';
2
6
  /** Canonical lowercase hexadecimal SPKI encoding for auth public keys. */
3
7
  export type EncodedAuthPublicKey = Brand<string, 'EncodedAuthPublicKey'>;
@@ -11,7 +15,12 @@ export type TransportKeyPair = {
11
15
  readonly privateKey: CryptoKey;
12
16
  readonly publicKey: CryptoKey;
13
17
  };
14
- /** Context bound into HKDF info and AEAD associated data for envelopes. */
18
+ /**
19
+ * Context bound into HKDF info and AEAD associated data for envelopes.
20
+ *
21
+ * The same fields also identify the public complaint slot for one dealer to
22
+ * recipient delivery.
23
+ */
15
24
  export type EnvelopeContext = {
16
25
  readonly sessionId: string;
17
26
  readonly rosterHash: string;
@@ -23,7 +32,12 @@ export type EnvelopeContext = {
23
32
  readonly protocolVersion: string;
24
33
  readonly suite: 'X25519';
25
34
  };
26
- /** Sender-ephemeral encrypted transport envelope. */
35
+ /**
36
+ * Sender-ephemeral encrypted transport envelope.
37
+ *
38
+ * DKG share distribution publishes this object on the board so the recipient
39
+ * can decrypt it and observers can later audit complaints against it.
40
+ */
27
41
  export type EncryptedEnvelope = EnvelopeContext & {
28
42
  readonly ephemeralPublicKey: EncodedTransportPublicKey;
29
43
  readonly iv: string;
@@ -1,13 +1,23 @@
1
+ /**
2
+ * Feldman commitment helpers used during DKG publication and transcript
3
+ * verification.
4
+ */
1
5
  import { type CryptoGroup } from '../core/index.js';
2
6
  import type { EncodedPoint } from '../core/types.js';
3
7
  import type { Share } from '../threshold/types.js';
4
8
  import type { FeldmanCommitments } from './types.js';
5
9
  export declare const evaluateCommitmentProduct: (commitments: readonly EncodedPoint[], index: number) => EncodedPoint;
6
10
  /**
7
- * Computes Feldman commitments for polynomial coefficients.
11
+ * Computes Feldman commitments for one secret polynomial.
12
+ *
13
+ * Dealers publish these commitments so everyone can later verify the shares
14
+ * they received.
8
15
  */
9
16
  export declare const generateFeldmanCommitments: (polynomial: readonly bigint[], group: CryptoGroup) => FeldmanCommitments;
10
17
  /**
11
18
  * Verifies a Feldman share against the published coefficient commitments.
19
+ *
20
+ * DKG verification uses this to reject dealers whose shares do not match the
21
+ * commitments they broadcast.
12
22
  */
13
23
  export declare const verifyFeldmanShare: (share: Share, commitments: FeldmanCommitments, group: CryptoGroup) => boolean;
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Feldman commitment helpers used during DKG publication and transcript
3
+ * verification.
4
+ */
1
5
  import { assertInSubgroup, assertPositiveParticipantIndex, assertScalarInZq, modQ, RISTRETTO_GROUP, assertCanonicalRistrettoGroup, } from '../core/index.js';
2
6
  import { decodePoint, encodePoint, multiplyBase, pointAdd, pointMultiply, RISTRETTO_ZERO, } from '../core/ristretto.js';
3
7
  export const evaluateCommitmentProduct = (commitments, index) => {
@@ -11,7 +15,10 @@ export const evaluateCommitmentProduct = (commitments, index) => {
11
15
  return encodePoint(result);
12
16
  };
13
17
  /**
14
- * Computes Feldman commitments for polynomial coefficients.
18
+ * Computes Feldman commitments for one secret polynomial.
19
+ *
20
+ * Dealers publish these commitments so everyone can later verify the shares
21
+ * they received.
15
22
  */
16
23
  export const generateFeldmanCommitments = (polynomial, group) => {
17
24
  assertCanonicalRistrettoGroup(group, 'Feldman commitment group');
@@ -24,6 +31,9 @@ export const generateFeldmanCommitments = (polynomial, group) => {
24
31
  };
25
32
  /**
26
33
  * Verifies a Feldman share against the published coefficient commitments.
34
+ *
35
+ * DKG verification uses this to reject dealers whose shares do not match the
36
+ * commitments they broadcast.
27
37
  */
28
38
  export const verifyFeldmanShare = (share, commitments, group) => {
29
39
  assertCanonicalRistrettoGroup(group, 'Feldman verification group');
@@ -1,17 +1,30 @@
1
+ /**
2
+ * Pedersen commitment and share helpers used during the dealer side of DKG and
3
+ * later transcript verification.
4
+ */
1
5
  import { type CryptoGroup } from '../core/index.js';
2
6
  import type { PedersenCommitments, PedersenShare } from './types.js';
3
7
  type Polynomial = readonly bigint[];
4
8
  /**
5
9
  * Computes Pedersen commitments for matching secret and blinding polynomials.
10
+ *
11
+ * This is the hiding commitment layer used before Feldman commitments are
12
+ * revealed and checked.
6
13
  */
7
14
  export declare const generatePedersenCommitments: (secretPolynomial: readonly bigint[], blindingPolynomial: readonly bigint[], group: CryptoGroup) => PedersenCommitments;
8
15
  /**
9
16
  * Derives indexed Pedersen share pairs from matching secret and blinding
10
17
  * polynomials.
18
+ *
19
+ * Dealers use these share pairs before encoding and encrypting them for each
20
+ * recipient.
11
21
  */
12
22
  export declare const derivePedersenShares: (secretPolynomial: Polynomial, blindingPolynomial: Polynomial, participantCount: number, q: bigint) => readonly PedersenShare[];
13
23
  /**
14
24
  * Verifies a Pedersen share pair against the published commitments.
25
+ *
26
+ * This is the low-level consistency check behind complaint validation and
27
+ * transcript replay.
15
28
  */
16
29
  export declare const verifyPedersenShare: (share: PedersenShare, commitments: PedersenCommitments, group: CryptoGroup) => boolean;
17
30
  export {};
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Pedersen commitment and share helpers used during the dealer side of DKG and
3
+ * later transcript verification.
4
+ */
1
5
  import { assertCanonicalRistrettoGroup, assertInSubgroup, assertPositiveParticipantIndex, assertScalarInZq, InvalidPayloadError, modQ, ThresholdViolationError, } from '../core/index.js';
2
6
  import { decodePoint, encodePoint, multiplyBase, pointAdd, pointMultiply, } from '../core/ristretto.js';
3
7
  import { evaluateCommitmentProduct } from './feldman.js';
@@ -11,6 +15,9 @@ const evaluatePolynomial = (polynomial, x, q) => {
11
15
  };
12
16
  /**
13
17
  * Computes Pedersen commitments for matching secret and blinding polynomials.
18
+ *
19
+ * This is the hiding commitment layer used before Feldman commitments are
20
+ * revealed and checked.
14
21
  */
15
22
  export const generatePedersenCommitments = (secretPolynomial, blindingPolynomial, group) => {
16
23
  assertCanonicalRistrettoGroup(group, 'Pedersen commitment group');
@@ -30,6 +37,9 @@ export const generatePedersenCommitments = (secretPolynomial, blindingPolynomial
30
37
  /**
31
38
  * Derives indexed Pedersen share pairs from matching secret and blinding
32
39
  * polynomials.
40
+ *
41
+ * Dealers use these share pairs before encoding and encrypting them for each
42
+ * recipient.
33
43
  */
34
44
  export const derivePedersenShares = (secretPolynomial, blindingPolynomial, participantCount, q) => {
35
45
  if (secretPolynomial.length !== blindingPolynomial.length) {
@@ -50,6 +60,9 @@ export const derivePedersenShares = (secretPolynomial, blindingPolynomial, parti
50
60
  };
51
61
  /**
52
62
  * Verifies a Pedersen share pair against the published commitments.
63
+ *
64
+ * This is the low-level consistency check behind complaint validation and
65
+ * transcript replay.
53
66
  */
54
67
  export const verifyPedersenShare = (share, commitments, group) => {
55
68
  assertCanonicalRistrettoGroup(group, 'Pedersen verification group');
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Public verifiable-secret-sharing helpers for Feldman and Pedersen
3
+ * commitments and shares.
4
+ *
5
+ * @module threshold-elgamal/vss
6
+ * @packageDocumentation
7
+ */
8
+ export { generateFeldmanCommitments, verifyFeldmanShare } from './feldman.js';
9
+ export { derivePedersenShares, generatePedersenCommitments, verifyPedersenShare, } from './pedersen.js';
10
+ export type { FeldmanCommitments, PedersenCommitments, PedersenShare, } from './types.js';
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Public verifiable-secret-sharing helpers for Feldman and Pedersen
3
+ * commitments and shares.
4
+ *
5
+ * @module threshold-elgamal/vss
6
+ * @packageDocumentation
7
+ */
8
+ export { generateFeldmanCommitments, verifyFeldmanShare } from './feldman.js';
9
+ export { derivePedersenShares, generatePedersenCommitments, verifyPedersenShare, } from './pedersen.js';
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Verifiable secret-sharing commitment and share types used by the GJKR DKG
3
+ * implementation and transcript verifier.
4
+ */
1
5
  import type { EncodedPoint } from '../core/types.js';
2
6
  /** Feldman coefficient commitments `A_m = a_m G`. */
3
7
  export type FeldmanCommitments = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "threshold-elgamal",
3
- "version": "1.0.9",
3
+ "version": "2.0.0",
4
4
  "description": "A browser-native TypeScript ElGamal library for Ristretto255-based research prototypes, shipping additive ElGamal, threshold decryption, protocol helpers, board auditing, transport primitives, and log-driven DKG state machines.",
5
5
  "author": "Piotr Piech <piotr@piech.dev>",
6
6
  "license": "MPL-2.0",
@@ -26,21 +26,22 @@
26
26
  "coverage:badge": "pnpm run coverage:node && tsx ./tools/generate-coverage-badge.ts",
27
27
  "smoke:pack": "tsx ./tools/ci/verify-packed-package.ts",
28
28
  "prebuild": "pnpm run check && pnpm run test",
29
- "build": "pnpm exec del-cli dist && tsc --project tsconfig.build.json && tsx ./tools/build/rewrite-dist-relative-imports.ts",
29
+ "build:dist": "pnpm exec del-cli dist && tsc --project tsconfig.build.json && tsx ./tools/build/rewrite-dist-relative-imports.ts",
30
+ "build": "pnpm run build:dist",
30
31
  "vectors:threshold": "tsx ./tools/generate-threshold-vectors.ts",
31
32
  "vectors:protocol": "tsx ./tools/generate-protocol-vectors.ts",
32
33
  "bench:micro": "tsx ./tools/benchmarks/microbench.ts",
33
34
  "bench:dkg": "tsx ./tools/benchmarks/dkg-benchmark.ts",
34
35
  "docs:api": "pnpm exec del-cli docs/src/content/docs/api/reference && tsx ./node_modules/typedoc/bin/typedoc --options typedoc.config.mjs && tsx ./typedoc/postprocess-site-docs.ts",
35
36
  "docs:dev": "pnpm run docs:api && astro dev --root docs",
36
- "docs:build:site": "pnpm exec del-cli docs/dist && astro build --root docs --silent",
37
- "docs:preview": "astro preview --root docs",
37
+ "docs:build:site": "pnpm run docs:api && pnpm exec del-cli docs/dist && astro build --root docs --silent",
38
+ "docs:preview": "pnpm run docs:build:site && astro preview --root docs",
38
39
  "verify:docs": "pnpm run docs:api && tsx ./typedoc/verify-docs.ts",
39
40
  "prepare": "husky"
40
41
  },
41
42
  "dependencies": {
42
- "@noble/curves": "^2.0.1",
43
- "@noble/hashes": "^2.0.1"
43
+ "@noble/curves": "^2.2.0",
44
+ "@noble/hashes": "^2.2.0"
44
45
  },
45
46
  "devDependencies": {
46
47
  "@astrojs/mdx": "^5.0.3",
@@ -49,25 +50,25 @@
49
50
  "@eslint/js": "^10.0.1",
50
51
  "@fontsource/ibm-plex-sans": "^5.2.8",
51
52
  "@fontsource/jetbrains-mono": "^5.2.8",
52
- "@types/node": "^25.5.2",
53
- "@typescript-eslint/eslint-plugin": "^8.58.1",
54
- "@typescript-eslint/parser": "^8.58.1",
53
+ "@types/node": "^25.6.0",
54
+ "@typescript-eslint/eslint-plugin": "^8.58.2",
55
+ "@typescript-eslint/parser": "^8.58.2",
55
56
  "@vitest/browser-playwright": "^4.1.4",
56
57
  "@vitest/coverage-v8": "^4.1.4",
57
- "astro": "^6.1.5",
58
+ "astro": "^6.1.7",
58
59
  "del-cli": "^7.0.0",
59
60
  "eslint": "^10.2.0",
60
61
  "eslint-config-prettier": "^10.1.8",
61
62
  "eslint-plugin-import-x": "^4.16.2",
62
63
  "eslint-plugin-only-error": "^1.0.2",
63
64
  "eslint-plugin-prettier": "^5.5.5",
64
- "globals": "^17.4.0",
65
+ "globals": "^17.5.0",
65
66
  "husky": "^9.1.7",
66
- "knip": "^5.67.0",
67
+ "knip": "^6.4.1",
67
68
  "playwright": "^1.59.1",
68
- "prettier": "^3.8.1",
69
+ "prettier": "^3.8.3",
69
70
  "tsx": "^4.21.0",
70
- "typedoc": "^0.28.18",
71
+ "typedoc": "^0.28.19",
71
72
  "typedoc-plugin-markdown": "^4.11.0",
72
73
  "typescript": "^6.0.2",
73
74
  "vite": "^8.0.8",
@@ -88,6 +89,34 @@
88
89
  ".": {
89
90
  "types": "./dist/index.d.ts",
90
91
  "import": "./dist/index.js"
92
+ },
93
+ "./core": {
94
+ "types": "./dist/core/public.d.ts",
95
+ "import": "./dist/core/public.js"
96
+ },
97
+ "./elgamal": {
98
+ "types": "./dist/elgamal/public.d.ts",
99
+ "import": "./dist/elgamal/public.js"
100
+ },
101
+ "./proofs": {
102
+ "types": "./dist/proofs/public.d.ts",
103
+ "import": "./dist/proofs/public.js"
104
+ },
105
+ "./threshold": {
106
+ "types": "./dist/threshold/public.d.ts",
107
+ "import": "./dist/threshold/public.js"
108
+ },
109
+ "./dkg": {
110
+ "types": "./dist/dkg/public.d.ts",
111
+ "import": "./dist/dkg/public.js"
112
+ },
113
+ "./vss": {
114
+ "types": "./dist/vss/public.d.ts",
115
+ "import": "./dist/vss/public.js"
116
+ },
117
+ "./protocol": {
118
+ "types": "./dist/protocol/public.d.ts",
119
+ "import": "./dist/protocol/public.js"
91
120
  }
92
121
  },
93
122
  "engines": {