threshold-elgamal 1.0.8 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -35
- package/dist/core/bigint.js +4 -0
- package/dist/core/bytes.js +4 -0
- package/dist/core/crypto.js +5 -0
- package/dist/core/errors.d.ts +50 -11
- package/dist/core/errors.js +50 -11
- package/dist/core/groups.d.ts +6 -1
- package/dist/core/groups.js +13 -2
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.js +4 -0
- package/dist/core/public.d.ts +13 -0
- package/dist/core/public.js +12 -0
- package/dist/core/random.js +4 -0
- package/dist/core/ristretto.d.ts +7 -0
- package/dist/core/ristretto.js +7 -0
- package/dist/core/types.d.ts +14 -6
- package/dist/core/validation.d.ts +45 -12
- package/dist/core/validation.js +52 -12
- package/dist/dkg/pedersen-share-codec.d.ts +12 -2
- package/dist/dkg/pedersen-share-codec.js +19 -2
- package/dist/dkg/public.d.ts +12 -0
- package/dist/dkg/public.js +11 -0
- package/dist/dkg/verification.d.ts +33 -14
- package/dist/dkg/verification.js +16 -12
- package/dist/elgamal/additive.d.ts +15 -3
- package/dist/elgamal/additive.js +22 -4
- package/dist/elgamal/bsgs.js +7 -0
- package/dist/elgamal/public.d.ts +11 -0
- package/dist/elgamal/public.js +10 -0
- package/dist/elgamal/types.d.ts +6 -0
- package/dist/index.d.ts +11 -25
- package/dist/index.js +10 -19
- package/dist/proofs/disjunctive.d.ts +10 -16
- package/dist/proofs/disjunctive.js +10 -16
- package/dist/proofs/dleq.d.ts +17 -13
- package/dist/proofs/dleq.js +11 -12
- package/dist/proofs/helpers.js +4 -0
- package/dist/proofs/nonces.js +6 -0
- package/dist/proofs/public.d.ts +12 -0
- package/dist/proofs/public.js +11 -0
- package/dist/proofs/schnorr.d.ts +10 -11
- package/dist/proofs/schnorr.js +10 -11
- package/dist/proofs/types.d.ts +30 -5
- package/dist/protocol/board-audit.d.ts +8 -3
- package/dist/protocol/board-audit.js +8 -2
- package/dist/protocol/builders.d.ts +77 -13
- package/dist/protocol/builders.js +83 -13
- package/dist/protocol/canonical-json.js +4 -0
- package/dist/protocol/manifest.d.ts +32 -15
- package/dist/protocol/manifest.js +39 -16
- package/dist/protocol/ordering.js +6 -0
- package/dist/protocol/payloads.d.ts +3 -3
- package/dist/protocol/payloads.js +7 -3
- package/dist/protocol/public.d.ts +15 -0
- package/dist/protocol/public.js +14 -0
- package/dist/protocol/transcript.js +4 -0
- package/dist/protocol/types.d.ts +98 -17
- package/dist/protocol/verification.d.ts +14 -7
- package/dist/protocol/verification.js +7 -5
- package/dist/protocol/voting-ballot-aggregation.d.ts +10 -2
- package/dist/protocol/voting-ballot-aggregation.js +6 -0
- package/dist/protocol/voting-ballots.d.ts +3 -5
- package/dist/protocol/voting-ballots.js +6 -5
- package/dist/protocol/voting-codecs.d.ts +3 -1
- package/dist/protocol/voting-codecs.js +7 -1
- package/dist/protocol/voting-decryption.d.ts +3 -5
- package/dist/protocol/voting-decryption.js +7 -5
- package/dist/protocol/voting-shared.js +6 -0
- package/dist/protocol/voting-verification.d.ts +27 -30
- package/dist/protocol/voting-verification.js +11 -25
- package/dist/serialize/encoding.js +4 -0
- package/dist/threshold/decrypt.d.ts +13 -5
- package/dist/threshold/decrypt.js +20 -5
- package/dist/threshold/public.d.ts +11 -0
- package/dist/threshold/public.js +10 -0
- package/dist/threshold/types.d.ts +23 -4
- package/dist/transport/auth.d.ts +10 -16
- package/dist/transport/auth.js +16 -16
- package/dist/transport/complaints.d.ts +2 -4
- package/dist/transport/complaints.js +8 -4
- package/dist/transport/envelopes.d.ts +5 -7
- package/dist/transport/envelopes.js +9 -7
- package/dist/transport/key-agreement.d.ts +15 -23
- package/dist/transport/key-agreement.js +21 -23
- package/dist/transport/types.d.ts +16 -2
- package/dist/vss/feldman.d.ts +11 -1
- package/dist/vss/feldman.js +11 -1
- package/dist/vss/pedersen.d.ts +13 -0
- package/dist/vss/pedersen.js +13 -0
- package/dist/vss/public.d.ts +10 -0
- package/dist/vss/public.js +9 -0
- package/dist/vss/types.d.ts +4 -0
- package/package.json +31 -3
package/README.md
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
1
|
# threshold-elgamal
|
|
2
2
|
|
|
3
|
-
[](https://www.npmjs.com/package/threshold-elgamal)
|
|
3
|
+
[](https://www.npmjs.com/package/threshold-elgamal)
|
|
5
4
|
|
|
6
5
|
---
|
|
7
6
|
|
|
8
|
-
[](https://github.com/Tenemo/threshold-elgamal/actions/workflows/ci.yml)
|
|
7
|
+
[](https://github.com/Tenemo/threshold-elgamal/actions/workflows/ci.yml)
|
|
9
8
|
[](https://tenemo.github.io/threshold-elgamal/coverage-summary.json)
|
|
10
|
-
[](https://github.com/Tenemo/threshold-elgamal/actions/workflows/pages.yml)
|
|
9
|
+
[](https://github.com/Tenemo/threshold-elgamal/actions/workflows/pages.yml)
|
|
11
10
|
|
|
12
11
|
---
|
|
13
12
|
|
|
14
|
-
[](https://nodejs.org/)
|
|
15
13
|
[](LICENSE)
|
|
16
14
|
|
|
17
|
-
`threshold-elgamal` is a browser-native TypeScript library for verifiable score-voting research prototypes.
|
|
15
|
+
`threshold-elgamal` is a browser-native TypeScript library for verifiable score-voting research prototypes. It focuses on one workflow:
|
|
18
16
|
|
|
19
17
|
- additive ElGamal on `ristretto255`
|
|
20
18
|
- honest-majority GJKR DKG
|
|
@@ -37,45 +35,40 @@ npm install threshold-elgamal
|
|
|
37
35
|
|
|
38
36
|
- Use ESM imports such as `import { createElectionManifest } from 'threshold-elgamal'`.
|
|
39
37
|
- Browsers need native `bigint` together with Web Crypto.
|
|
40
|
-
- Node
|
|
38
|
+
- Node must satisfy the package `engines.node` requirement and expose `globalThis.crypto`.
|
|
41
39
|
- Authentication signatures require Web Crypto `Ed25519`.
|
|
42
40
|
- Transport share exchange requires Web Crypto `X25519`.
|
|
43
41
|
|
|
44
|
-
See [Runtime and compatibility](https://tenemo.github.io/threshold-elgamal/guides/runtime-and-compatibility/) for
|
|
45
|
-
|
|
46
|
-
## Start here
|
|
47
|
-
|
|
48
|
-
- [Verifying a public board](https://tenemo.github.io/threshold-elgamal/guides/verifying-a-public-board/): start here for `tryVerifyElectionCeremony(...)` and `verifyElectionCeremony(...)`.
|
|
49
|
-
- [Browser and worker usage](https://tenemo.github.io/threshold-elgamal/guides/browser-and-worker-usage/): start here for key generation, manifest setup, and encrypted transport envelopes.
|
|
50
|
-
- [Published payload examples](https://tenemo.github.io/threshold-elgamal/guides/published-payload-examples/): start here if you need concrete JSON, posting, or persistence patterns.
|
|
51
|
-
- [Honest-majority voting flow](https://tenemo.github.io/threshold-elgamal/guides/three-participant-voting-flow/): read this for the supported phase-by-phase transcript story.
|
|
42
|
+
See [Runtime and compatibility](https://tenemo.github.io/threshold-elgamal/guides/runtime-and-compatibility/) for environment requirements.
|
|
52
43
|
|
|
53
44
|
## Documentation
|
|
54
45
|
|
|
55
|
-
-
|
|
56
|
-
-
|
|
57
|
-
-
|
|
46
|
+
- Homepage: [tenemo.github.io/threshold-elgamal](https://tenemo.github.io/threshold-elgamal/)
|
|
47
|
+
- Getting started: [tenemo.github.io/threshold-elgamal/guides/getting-started](https://tenemo.github.io/threshold-elgamal/guides/getting-started/)
|
|
48
|
+
- Runtime and compatibility: [tenemo.github.io/threshold-elgamal/guides/runtime-and-compatibility](https://tenemo.github.io/threshold-elgamal/guides/runtime-and-compatibility/)
|
|
58
49
|
- Browser and worker usage: [tenemo.github.io/threshold-elgamal/guides/browser-and-worker-usage](https://tenemo.github.io/threshold-elgamal/guides/browser-and-worker-usage/)
|
|
59
|
-
- Published payload examples: [tenemo.github.io/threshold-elgamal/guides/published-payload-examples](https://tenemo.github.io/threshold-elgamal/guides/published-payload-examples/)
|
|
60
50
|
- Honest-majority voting flow: [tenemo.github.io/threshold-elgamal/guides/three-participant-voting-flow](https://tenemo.github.io/threshold-elgamal/guides/three-participant-voting-flow/)
|
|
61
|
-
-
|
|
51
|
+
- Published payload examples: [tenemo.github.io/threshold-elgamal/guides/published-payload-examples](https://tenemo.github.io/threshold-elgamal/guides/published-payload-examples/)
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
- Verifying a public board: [tenemo.github.io/threshold-elgamal/guides/verifying-a-public-board](https://tenemo.github.io/threshold-elgamal/guides/verifying-a-public-board/)
|
|
62
56
|
- Security boundary: [tenemo.github.io/threshold-elgamal/guides/security-and-non-goals](https://tenemo.github.io/threshold-elgamal/guides/security-and-non-goals/)
|
|
63
57
|
- Production voting safety review: [tenemo.github.io/threshold-elgamal/guides/production-voting-safety-review](https://tenemo.github.io/threshold-elgamal/guides/production-voting-safety-review/)
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
64
61
|
- API docs: [tenemo.github.io/threshold-elgamal/api](https://tenemo.github.io/threshold-elgamal/api/)
|
|
65
62
|
|
|
66
63
|
## Browser support
|
|
67
64
|
|
|
68
|
-
The
|
|
65
|
+
The cryptographic browser path is fixed:
|
|
69
66
|
|
|
70
67
|
- `Ed25519` for protocol payload signatures
|
|
71
68
|
- `X25519` for encrypted share transport
|
|
72
69
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
- Chrome and Edge `137+`
|
|
76
|
-
- Firefox `130+`
|
|
77
|
-
- Safari `18.4+`
|
|
78
|
-
- iOS and iPadOS browsers on the Safari `18.4+` WebKit generation
|
|
70
|
+
- Use modern browsers that expose Web Crypto `Ed25519`, Web Crypto `X25519`, and native `bigint`
|
|
71
|
+
- Validate your target environments with `pnpm exec tsx ./tools/ci/verify-browser-compat.ts` before deployment
|
|
79
72
|
|
|
80
73
|
Older browsers, stale embedded webviews, and runtimes without Web Crypto `X25519` support are not supported.
|
|
81
74
|
|
|
@@ -178,7 +171,7 @@ if (!result.ok) {
|
|
|
178
171
|
}
|
|
179
172
|
```
|
|
180
173
|
|
|
181
|
-
The root package
|
|
174
|
+
The root package exposes the workflow-facing builders for the signed protocol payloads used across the documented ceremony, including:
|
|
182
175
|
|
|
183
176
|
- manifest publication
|
|
184
177
|
- registration
|
|
@@ -193,13 +186,14 @@ The root package also exposes builders for the signed protocol payloads used acr
|
|
|
193
186
|
- decryption shares
|
|
194
187
|
- tally publication
|
|
195
188
|
|
|
196
|
-
For the reveal path, the public
|
|
189
|
+
For the reveal path, the workflow-facing API and the advanced public submodules split responsibilities intentionally:
|
|
197
190
|
|
|
198
|
-
- prepare the accepted aggregate with `prepareAggregateForDecryption(...)`
|
|
199
|
-
- compute each partial share with `createDecryptionShare(...)`
|
|
200
|
-
- prove
|
|
191
|
+
- prepare the accepted aggregate with `prepareAggregateForDecryption(...)` from `threshold-elgamal/threshold`
|
|
192
|
+
- compute each partial share with `createDecryptionShare(...)` from `threshold-elgamal/threshold`
|
|
193
|
+
- prove it with `createDLEQProof(...)` from `threshold-elgamal/proofs`
|
|
194
|
+
- publish it with `createDecryptionSharePayload(...)` from `threshold-elgamal`
|
|
201
195
|
|
|
202
|
-
After collecting a threshold subset, recover the tally with `combineDecryptionShares(...)` against the prepared aggregate ciphertext.
|
|
196
|
+
After collecting a threshold subset, recover the tally with `combineDecryptionShares(...)` from `threshold-elgamal/threshold` against the prepared aggregate ciphertext.
|
|
203
197
|
|
|
204
198
|
For concrete posted JSON shapes, use [Published payload examples](https://tenemo.github.io/threshold-elgamal/guides/published-payload-examples/).
|
|
205
199
|
|
|
@@ -224,9 +218,9 @@ What it does not claim:
|
|
|
224
218
|
- constant-time JavaScript `bigint` execution
|
|
225
219
|
- production readiness
|
|
226
220
|
|
|
227
|
-
`ballot-close` is an auditable administrative cutoff, not a fairness proof about board arrival order. The library proves
|
|
221
|
+
`ballot-close` is an auditable administrative cutoff, not a fairness proof about board arrival order. The library proves which ballots count, not whether the organizer waited long enough before closing.
|
|
228
222
|
|
|
229
|
-
For a production-threat-model verdict that maps these boundaries to the
|
|
223
|
+
For a production-threat-model verdict that maps these boundaries to the verifier and tests, read the [production voting safety review](https://tenemo.github.io/threshold-elgamal/guides/production-voting-safety-review/).
|
|
230
224
|
|
|
231
225
|
## Development
|
|
232
226
|
|
package/dist/core/bigint.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finite-field arithmetic helpers shared by proofs, verifiable secret sharing,
|
|
3
|
+
* threshold reconstruction, and transcript verification.
|
|
4
|
+
*/
|
|
1
5
|
import { InvalidScalarError } from './errors.js';
|
|
2
6
|
const assertPositiveModulus = (modulus) => {
|
|
3
7
|
if (modulus <= 0n) {
|
package/dist/core/bytes.js
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Byte, hex, and buffer-shape conversion helpers used by hashing,
|
|
3
|
+
* serialization, signatures, and transport code throughout the package.
|
|
4
|
+
*/
|
|
1
5
|
import { InvalidPayloadError } from './errors.js';
|
|
2
6
|
const hexPattern = /^[0-9a-f]+$/i;
|
|
3
7
|
const defaultHexErrorMessage = 'Hex input must be a non-empty even-length hexadecimal string';
|
package/dist/core/crypto.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Runtime crypto helpers that normalize Web Crypto access for hashing,
|
|
3
|
+
* HKDF-based key derivation, and UTF-8 encoding across browser and Node
|
|
4
|
+
* runtimes.
|
|
5
|
+
*/
|
|
1
6
|
import { toBufferSource } from './bytes.js';
|
|
2
7
|
import { InvalidScalarError, UnsupportedSuiteError } from './errors.js';
|
|
3
8
|
const textEncoder = new TextEncoder();
|
package/dist/core/errors.d.ts
CHANGED
|
@@ -1,37 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared error taxonomy for the package.
|
|
3
|
+
*
|
|
4
|
+
* Public helpers throw these errors when callers violate mathematical,
|
|
5
|
+
* encoding, transcript, or workflow invariants.
|
|
6
|
+
*/
|
|
1
7
|
declare class ThresholdElGamalError extends Error {
|
|
2
8
|
constructor(message: string);
|
|
3
9
|
}
|
|
4
|
-
/**
|
|
10
|
+
/**
|
|
11
|
+
* Raised when a scalar value falls outside the expected field or subgroup
|
|
12
|
+
* domain for the current operation.
|
|
13
|
+
*/
|
|
5
14
|
export declare class InvalidScalarError extends ThresholdElGamalError {
|
|
6
15
|
}
|
|
7
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Raised when a point or public key is not a canonical member of the selected
|
|
18
|
+
* cryptographic group.
|
|
19
|
+
*/
|
|
8
20
|
export declare class InvalidGroupElementError extends ThresholdElGamalError {
|
|
9
21
|
}
|
|
10
|
-
/**
|
|
22
|
+
/**
|
|
23
|
+
* Raised when a participant index falls outside the supported `1..n`
|
|
24
|
+
* numbering scheme used across the protocol.
|
|
25
|
+
*/
|
|
11
26
|
export declare class IndexOutOfRangeError extends ThresholdElGamalError {
|
|
12
27
|
}
|
|
13
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* Raised when a payload, transcript field, manifest field, or serialized value
|
|
30
|
+
* does not satisfy the package's canonical encoding rules.
|
|
31
|
+
*/
|
|
14
32
|
export declare class InvalidPayloadError extends ThresholdElGamalError {
|
|
15
33
|
}
|
|
16
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Raised when a Schnorr, DLEQ, or disjunctive proof transcript fails
|
|
36
|
+
* structural checks or cryptographic verification.
|
|
37
|
+
*/
|
|
17
38
|
export declare class InvalidProofError extends ThresholdElGamalError {
|
|
18
39
|
}
|
|
19
|
-
/**
|
|
40
|
+
/**
|
|
41
|
+
* Raised when the requested suite or required runtime capability is unavailable
|
|
42
|
+
* in the current environment.
|
|
43
|
+
*/
|
|
20
44
|
export declare class UnsupportedSuiteError extends ThresholdElGamalError {
|
|
21
45
|
}
|
|
22
|
-
/**
|
|
46
|
+
/**
|
|
47
|
+
* Raised when an additive plaintext falls outside the explicitly bounded domain
|
|
48
|
+
* that the current workflow promised to support.
|
|
49
|
+
*/
|
|
23
50
|
export declare class PlaintextDomainError extends ThresholdElGamalError {
|
|
24
51
|
}
|
|
25
|
-
/**
|
|
52
|
+
/**
|
|
53
|
+
* Raised when a serialized share, decrypted share envelope, or reconstructed
|
|
54
|
+
* share set fails threshold-specific validation.
|
|
55
|
+
*/
|
|
26
56
|
export declare class InvalidShareError extends ThresholdElGamalError {
|
|
27
57
|
}
|
|
28
|
-
/**
|
|
58
|
+
/**
|
|
59
|
+
* Raised when a published payload claims to belong to a protocol phase that
|
|
60
|
+
* does not match the supported ceremony state machine.
|
|
61
|
+
*/
|
|
29
62
|
export declare class PhaseViolationError extends ThresholdElGamalError {
|
|
30
63
|
}
|
|
31
|
-
/**
|
|
64
|
+
/**
|
|
65
|
+
* Raised when threshold parameters or participant counts violate the supported
|
|
66
|
+
* `1 <= k <= n` relationship or the package's honest-majority policy.
|
|
67
|
+
*/
|
|
32
68
|
export declare class ThresholdViolationError extends ThresholdElGamalError {
|
|
33
69
|
}
|
|
34
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Raised when transcript hashes, manifest hashes, or other canonical digest
|
|
72
|
+
* commitments do not match the values claimed by published payloads.
|
|
73
|
+
*/
|
|
35
74
|
export declare class TranscriptMismatchError extends ThresholdElGamalError {
|
|
36
75
|
}
|
|
37
76
|
export {};
|
package/dist/core/errors.js
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared error taxonomy for the package.
|
|
3
|
+
*
|
|
4
|
+
* Public helpers throw these errors when callers violate mathematical,
|
|
5
|
+
* encoding, transcript, or workflow invariants.
|
|
6
|
+
*/
|
|
1
7
|
class ThresholdElGamalError extends Error {
|
|
2
8
|
constructor(message) {
|
|
3
9
|
super(message);
|
|
@@ -5,36 +11,69 @@ class ThresholdElGamalError extends Error {
|
|
|
5
11
|
Object.setPrototypeOf(this, new.target.prototype);
|
|
6
12
|
}
|
|
7
13
|
}
|
|
8
|
-
/**
|
|
14
|
+
/**
|
|
15
|
+
* Raised when a scalar value falls outside the expected field or subgroup
|
|
16
|
+
* domain for the current operation.
|
|
17
|
+
*/
|
|
9
18
|
export class InvalidScalarError extends ThresholdElGamalError {
|
|
10
19
|
}
|
|
11
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* Raised when a point or public key is not a canonical member of the selected
|
|
22
|
+
* cryptographic group.
|
|
23
|
+
*/
|
|
12
24
|
export class InvalidGroupElementError extends ThresholdElGamalError {
|
|
13
25
|
}
|
|
14
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Raised when a participant index falls outside the supported `1..n`
|
|
28
|
+
* numbering scheme used across the protocol.
|
|
29
|
+
*/
|
|
15
30
|
export class IndexOutOfRangeError extends ThresholdElGamalError {
|
|
16
31
|
}
|
|
17
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* Raised when a payload, transcript field, manifest field, or serialized value
|
|
34
|
+
* does not satisfy the package's canonical encoding rules.
|
|
35
|
+
*/
|
|
18
36
|
export class InvalidPayloadError extends ThresholdElGamalError {
|
|
19
37
|
}
|
|
20
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* Raised when a Schnorr, DLEQ, or disjunctive proof transcript fails
|
|
40
|
+
* structural checks or cryptographic verification.
|
|
41
|
+
*/
|
|
21
42
|
export class InvalidProofError extends ThresholdElGamalError {
|
|
22
43
|
}
|
|
23
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Raised when the requested suite or required runtime capability is unavailable
|
|
46
|
+
* in the current environment.
|
|
47
|
+
*/
|
|
24
48
|
export class UnsupportedSuiteError extends ThresholdElGamalError {
|
|
25
49
|
}
|
|
26
|
-
/**
|
|
50
|
+
/**
|
|
51
|
+
* Raised when an additive plaintext falls outside the explicitly bounded domain
|
|
52
|
+
* that the current workflow promised to support.
|
|
53
|
+
*/
|
|
27
54
|
export class PlaintextDomainError extends ThresholdElGamalError {
|
|
28
55
|
}
|
|
29
|
-
/**
|
|
56
|
+
/**
|
|
57
|
+
* Raised when a serialized share, decrypted share envelope, or reconstructed
|
|
58
|
+
* share set fails threshold-specific validation.
|
|
59
|
+
*/
|
|
30
60
|
export class InvalidShareError extends ThresholdElGamalError {
|
|
31
61
|
}
|
|
32
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Raised when a published payload claims to belong to a protocol phase that
|
|
64
|
+
* does not match the supported ceremony state machine.
|
|
65
|
+
*/
|
|
33
66
|
export class PhaseViolationError extends ThresholdElGamalError {
|
|
34
67
|
}
|
|
35
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* Raised when threshold parameters or participant counts violate the supported
|
|
70
|
+
* `1 <= k <= n` relationship or the package's honest-majority policy.
|
|
71
|
+
*/
|
|
36
72
|
export class ThresholdViolationError extends ThresholdElGamalError {
|
|
37
73
|
}
|
|
38
|
-
/**
|
|
74
|
+
/**
|
|
75
|
+
* Raised when transcript hashes, manifest hashes, or other canonical digest
|
|
76
|
+
* commitments do not match the values claimed by published payloads.
|
|
77
|
+
*/
|
|
39
78
|
export class TranscriptMismatchError extends ThresholdElGamalError {
|
|
40
79
|
}
|
package/dist/core/groups.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { CryptoGroup } from './types.js';
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* Immutable definition of the built-in `ristretto255` tally group.
|
|
4
|
+
*
|
|
5
|
+
* Every public cryptographic workflow in this package ultimately routes
|
|
6
|
+
* through this suite definition.
|
|
7
|
+
*/
|
|
3
8
|
export declare const RISTRETTO_GROUP: CryptoGroup;
|
|
4
9
|
export declare const assertCanonicalRistrettoGroup: (group: CryptoGroup, label?: string) => void;
|
package/dist/core/groups.js
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in group definitions and suite guard rails.
|
|
3
|
+
*
|
|
4
|
+
* The public API is intentionally tied to one canonical suite,
|
|
5
|
+
* `ristretto255`, and this module makes that choice explicit.
|
|
6
|
+
*/
|
|
1
7
|
import { UnsupportedSuiteError } from './errors.js';
|
|
2
8
|
import { derivePedersenGenerator, RISTRETTO_BYTE_LENGTH } from './ristretto.js';
|
|
3
|
-
/**
|
|
9
|
+
/**
|
|
10
|
+
* Immutable definition of the built-in `ristretto255` tally group.
|
|
11
|
+
*
|
|
12
|
+
* Every public cryptographic workflow in this package ultimately routes
|
|
13
|
+
* through this suite definition.
|
|
14
|
+
*/
|
|
4
15
|
export const RISTRETTO_GROUP = Object.freeze({
|
|
5
16
|
name: 'ristretto255',
|
|
6
17
|
byteLength: RISTRETTO_BYTE_LENGTH,
|
|
@@ -20,6 +31,6 @@ const sameCanonicalRistrettoGroup = (group) => group.name === RISTRETTO_GROUP.na
|
|
|
20
31
|
export const assertCanonicalRistrettoGroup = (group, label = 'Group') => {
|
|
21
32
|
const normalizedLabel = label.length > 0 ? `${label[0].toLowerCase()}${label.slice(1)}` : label;
|
|
22
33
|
if (!sameCanonicalRistrettoGroup(group)) {
|
|
23
|
-
throw new UnsupportedSuiteError(`${normalizedLabel} must match the
|
|
34
|
+
throw new UnsupportedSuiteError(`${normalizedLabel} must match the canonical ristretto255 group definition`);
|
|
24
35
|
}
|
|
25
36
|
};
|
package/dist/core/index.d.ts
CHANGED
package/dist/core/index.js
CHANGED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level core helpers for arithmetic, error handling, and group constants.
|
|
3
|
+
*
|
|
4
|
+
* Use this module when you need primitives that sit below the voting workflow
|
|
5
|
+
* surface exposed by the root package.
|
|
6
|
+
*
|
|
7
|
+
* @module threshold-elgamal/core
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export { IndexOutOfRangeError, InvalidGroupElementError, InvalidPayloadError, InvalidProofError, InvalidScalarError, InvalidShareError, PhaseViolationError, PlaintextDomainError, ThresholdViolationError, TranscriptMismatchError, UnsupportedSuiteError, } from './errors.js';
|
|
11
|
+
export { modQ } from './bigint.js';
|
|
12
|
+
export { RISTRETTO_GROUP } from './groups.js';
|
|
13
|
+
export type { EncodedPoint } from './types.js';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level core helpers for arithmetic, error handling, and group constants.
|
|
3
|
+
*
|
|
4
|
+
* Use this module when you need primitives that sit below the voting workflow
|
|
5
|
+
* surface exposed by the root package.
|
|
6
|
+
*
|
|
7
|
+
* @module threshold-elgamal/core
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
export { IndexOutOfRangeError, InvalidGroupElementError, InvalidPayloadError, InvalidProofError, InvalidScalarError, InvalidShareError, PhaseViolationError, PlaintextDomainError, ThresholdViolationError, TranscriptMismatchError, UnsupportedSuiteError, } from './errors.js';
|
|
11
|
+
export { modQ } from './bigint.js';
|
|
12
|
+
export { RISTRETTO_GROUP } from './groups.js';
|
package/dist/core/random.js
CHANGED
package/dist/core/ristretto.d.ts
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level Ristretto255 point and scalar operations.
|
|
3
|
+
*
|
|
4
|
+
* Higher-level modules such as additive ElGamal, proofs, VSS, and threshold
|
|
5
|
+
* reconstruction build on these wrappers instead of calling the curve library
|
|
6
|
+
* directly.
|
|
7
|
+
*/
|
|
1
8
|
import { ristretto255 } from '@noble/curves/ed25519.js';
|
|
2
9
|
import type { EncodedPoint } from './types.js';
|
|
3
10
|
type InternalPoint = InstanceType<typeof ristretto255.Point>;
|
package/dist/core/ristretto.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level Ristretto255 point and scalar operations.
|
|
3
|
+
*
|
|
4
|
+
* Higher-level modules such as additive ElGamal, proofs, VSS, and threshold
|
|
5
|
+
* reconstruction build on these wrappers instead of calling the curve library
|
|
6
|
+
* directly.
|
|
7
|
+
*/
|
|
1
8
|
import { ristretto255, ristretto255_hasher } from '@noble/curves/ed25519.js';
|
|
2
9
|
import { sha512 } from '@noble/hashes/sha2.js';
|
|
3
10
|
import { bytesToBigInt, bytesToBigIntLE, bytesToHex, hexToBytes, } from './bytes.js';
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Foundational nominal and suite types shared across the package.
|
|
3
|
+
*/
|
|
1
4
|
/**
|
|
2
5
|
* Nominal typing helper used to distinguish compatible runtime values in the
|
|
3
6
|
* type system.
|
|
@@ -5,13 +8,18 @@
|
|
|
5
8
|
export type Brand<T, TBrand extends string> = T & {
|
|
6
9
|
readonly __brand: TBrand;
|
|
7
10
|
};
|
|
8
|
-
/** @internal Canonical name for the
|
|
11
|
+
/** @internal Canonical name for the built-in Ristretto255 suite. */
|
|
9
12
|
export type GroupName = 'ristretto255';
|
|
10
|
-
/** @internal Accepted helper input identifiers for the
|
|
13
|
+
/** @internal Accepted helper input identifiers for the built-in Ristretto suite. */
|
|
11
14
|
export type GroupIdentifier = GroupName;
|
|
12
|
-
/**
|
|
15
|
+
/**
|
|
16
|
+
* Canonical 32-byte Ristretto point encoding exposed at the public boundary.
|
|
17
|
+
*
|
|
18
|
+
* Public helpers use this branded string type to distinguish encoded points
|
|
19
|
+
* from ordinary hex strings.
|
|
20
|
+
*/
|
|
13
21
|
export type EncodedPoint = Brand<string, 'EncodedPoint'>;
|
|
14
|
-
/** @internal Immutable
|
|
22
|
+
/** @internal Immutable group definition for the built-in suite. */
|
|
15
23
|
export type CryptoGroup = {
|
|
16
24
|
/** Canonical suite name. */
|
|
17
25
|
readonly name: GroupName;
|
|
@@ -29,7 +37,7 @@ export type CryptoGroup = {
|
|
|
29
37
|
readonly securityEstimate: number;
|
|
30
38
|
};
|
|
31
39
|
/**
|
|
32
|
-
* Random byte source injected into sampling helpers for deterministic
|
|
33
|
-
* or custom runtime integration.
|
|
40
|
+
* Random byte source injected into sampling helpers for deterministic tests,
|
|
41
|
+
* reproducible vectors, or custom runtime integration.
|
|
34
42
|
*/
|
|
35
43
|
export type RandomBytesSource = (length: number) => Uint8Array;
|
|
@@ -1,6 +1,16 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* Returns `true` when the value is a canonical non-identity Ristretto point.
|
|
3
|
+
*
|
|
4
|
+
* This is the predicate used for public keys and most commitment elements.
|
|
5
|
+
*/
|
|
2
6
|
export declare const isInSubgroup: (value: string) => boolean;
|
|
3
|
-
/**
|
|
7
|
+
/**
|
|
8
|
+
* Returns `true` when the value is a canonical Ristretto point, including the
|
|
9
|
+
* identity element.
|
|
10
|
+
*
|
|
11
|
+
* This variant is used for ciphertext components and transcript values that
|
|
12
|
+
* are allowed to land on the identity.
|
|
13
|
+
*/
|
|
4
14
|
export declare const isInSubgroupOrIdentity: (value: string) => boolean;
|
|
5
15
|
/**
|
|
6
16
|
* Validates that a scalar belongs to `Z_q`.
|
|
@@ -30,25 +40,48 @@ export declare const assertPlaintextAdditive: (value: bigint, bound: bigint, q:
|
|
|
30
40
|
*/
|
|
31
41
|
export declare const assertThreshold: (threshold: number, participantCount: number) => void;
|
|
32
42
|
/**
|
|
33
|
-
* Derives the
|
|
43
|
+
* Derives the supported honest-majority threshold `ceil(n / 2)`.
|
|
34
44
|
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
45
|
+
* This is the threshold policy used by the package's DKG and full voting flow.
|
|
46
|
+
* Callers do not choose a custom `k`; the verifier derives it from the
|
|
47
|
+
* accepted registration roster.
|
|
38
48
|
*/
|
|
39
49
|
export declare const majorityThreshold: (participantCount: number) => number;
|
|
40
50
|
/**
|
|
41
|
-
* Validates that the supplied threshold matches the
|
|
51
|
+
* Validates that the supplied threshold matches the library's GJKR
|
|
42
52
|
* honest-majority policy.
|
|
43
53
|
*/
|
|
44
54
|
export declare const assertMajorityThreshold: (threshold: number, participantCount: number) => number;
|
|
45
|
-
/**
|
|
55
|
+
/**
|
|
56
|
+
* Validates a 1-based participant index without assuming a fixed participant
|
|
57
|
+
* count.
|
|
58
|
+
*
|
|
59
|
+
* The package consistently numbers trustees and voters from `1`.
|
|
60
|
+
*/
|
|
46
61
|
export declare const assertPositiveParticipantIndex: (index: number) => void;
|
|
47
|
-
/**
|
|
62
|
+
/**
|
|
63
|
+
* Validates a 1-based participant index against a fixed participant count.
|
|
64
|
+
*
|
|
65
|
+
* This is the usual check for published payloads that already sit inside a
|
|
66
|
+
* frozen roster.
|
|
67
|
+
*/
|
|
48
68
|
export declare const assertValidParticipantIndex: (index: number, participantCount: number) => void;
|
|
49
|
-
/**
|
|
69
|
+
/**
|
|
70
|
+
* Validates that a value is a canonical non-identity Ristretto point.
|
|
71
|
+
*
|
|
72
|
+
* This is the assertion form of {@link isInSubgroup}.
|
|
73
|
+
*/
|
|
50
74
|
export declare const assertInSubgroup: (value: string) => void;
|
|
51
|
-
/**
|
|
75
|
+
/**
|
|
76
|
+
* Validates that a value is a canonical Ristretto point, including identity.
|
|
77
|
+
*
|
|
78
|
+
* This is the assertion form of {@link isInSubgroupOrIdentity}.
|
|
79
|
+
*/
|
|
52
80
|
export declare const assertInSubgroupOrIdentity: (value: string) => void;
|
|
53
|
-
/**
|
|
81
|
+
/**
|
|
82
|
+
* Validates a public key as a canonical non-identity Ristretto point.
|
|
83
|
+
*
|
|
84
|
+
* Public keys, verification keys, and commitment generators all route through
|
|
85
|
+
* this helper.
|
|
86
|
+
*/
|
|
54
87
|
export declare const assertValidPublicKey: (value: string) => void;
|