@digitaldefiance/ecies-lib 4.6.3 → 4.7.1

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 (119) hide show
  1. package/README.md +420 -0
  2. package/package.json +4 -10
  3. package/src/builders/ecies-builder.d.ts +1 -1
  4. package/src/builders/ecies-builder.d.ts.map +1 -1
  5. package/src/builders/ecies-builder.js +2 -2
  6. package/src/builders/ecies-builder.js.map +1 -1
  7. package/src/email-string.js +2 -3
  8. package/src/email-string.js.map +1 -1
  9. package/src/i18n-setup.js +1 -1
  10. package/src/i18n-setup.js.map +1 -1
  11. package/src/index.d.ts +1 -0
  12. package/src/index.d.ts.map +1 -1
  13. package/src/index.js +2 -0
  14. package/src/index.js.map +1 -1
  15. package/src/interfaces/index.d.ts +1 -0
  16. package/src/interfaces/index.d.ts.map +1 -1
  17. package/src/interfaces/index.js +3 -0
  18. package/src/interfaces/index.js.map +1 -1
  19. package/src/interfaces/voting-poll.d.ts +455 -0
  20. package/src/interfaces/voting-poll.d.ts.map +1 -0
  21. package/src/interfaces/voting-poll.js +54 -0
  22. package/src/interfaces/voting-poll.js.map +1 -0
  23. package/src/isolated-private.d.ts +0 -4
  24. package/src/isolated-private.d.ts.map +1 -1
  25. package/src/isolated-private.js +0 -13
  26. package/src/isolated-private.js.map +1 -1
  27. package/src/isolated-public.d.ts +4 -2
  28. package/src/isolated-public.d.ts.map +1 -1
  29. package/src/isolated-public.js +10 -8
  30. package/src/isolated-public.js.map +1 -1
  31. package/src/lib/voting/audit.d.ts +79 -0
  32. package/src/lib/voting/audit.d.ts.map +1 -0
  33. package/src/lib/voting/audit.js +188 -0
  34. package/src/lib/voting/audit.js.map +1 -0
  35. package/src/lib/voting/bulletin-board.d.ts +94 -0
  36. package/src/lib/voting/bulletin-board.d.ts.map +1 -0
  37. package/src/lib/voting/bulletin-board.js +290 -0
  38. package/src/lib/voting/bulletin-board.js.map +1 -0
  39. package/src/lib/voting/encoder.d.ts +42 -0
  40. package/src/lib/voting/encoder.d.ts.map +1 -0
  41. package/src/lib/voting/encoder.js +157 -0
  42. package/src/lib/voting/encoder.js.map +1 -0
  43. package/src/lib/voting/event-logger.d.ts +81 -0
  44. package/src/lib/voting/event-logger.d.ts.map +1 -0
  45. package/src/lib/voting/event-logger.js +165 -0
  46. package/src/lib/voting/event-logger.js.map +1 -0
  47. package/src/lib/voting/examples.d.ts +30 -0
  48. package/src/lib/voting/examples.d.ts.map +1 -0
  49. package/src/lib/voting/examples.js +153 -0
  50. package/src/lib/voting/examples.js.map +1 -0
  51. package/src/lib/voting/factory.d.ts +35 -0
  52. package/src/lib/voting/factory.d.ts.map +1 -0
  53. package/src/lib/voting/factory.js +57 -0
  54. package/src/lib/voting/factory.js.map +1 -0
  55. package/src/lib/voting/index.d.ts +44 -0
  56. package/src/lib/voting/index.d.ts.map +1 -0
  57. package/src/lib/voting/index.js +60 -0
  58. package/src/lib/voting/index.js.map +1 -0
  59. package/src/lib/voting/poll-core.d.ts +55 -0
  60. package/src/lib/voting/poll-core.d.ts.map +1 -0
  61. package/src/lib/voting/poll-core.js +225 -0
  62. package/src/lib/voting/poll-core.js.map +1 -0
  63. package/src/lib/voting/poll.d.ts +124 -0
  64. package/src/lib/voting/poll.d.ts.map +1 -0
  65. package/src/lib/voting/poll.js +323 -0
  66. package/src/lib/voting/poll.js.map +1 -0
  67. package/src/lib/voting/security.d.ts +33 -0
  68. package/src/lib/voting/security.d.ts.map +1 -0
  69. package/src/lib/voting/security.js +68 -0
  70. package/src/lib/voting/security.js.map +1 -0
  71. package/src/lib/voting/tallier.d.ts +35 -0
  72. package/src/lib/voting/tallier.d.ts.map +1 -0
  73. package/src/lib/voting/tallier.js +415 -0
  74. package/src/lib/voting/tallier.js.map +1 -0
  75. package/src/lib/voting/types.d.ts +145 -0
  76. package/src/lib/voting/types.d.ts.map +1 -0
  77. package/src/lib/voting/types.js +48 -0
  78. package/src/lib/voting/types.js.map +1 -0
  79. package/src/member.d.ts +2 -2
  80. package/src/member.d.ts.map +1 -1
  81. package/src/member.js +2 -2
  82. package/src/member.js.map +1 -1
  83. package/src/secure-string.d.ts +2 -2
  84. package/src/secure-string.d.ts.map +1 -1
  85. package/src/secure-string.js +2 -2
  86. package/src/secure-string.js.map +1 -1
  87. package/src/services/aes-gcm.js.map +1 -1
  88. package/src/services/chunk-processor.d.ts +2 -2
  89. package/src/services/chunk-processor.d.ts.map +1 -1
  90. package/src/services/chunk-processor.js +3 -3
  91. package/src/services/chunk-processor.js.map +1 -1
  92. package/src/services/ecies/service.d.ts +3 -0
  93. package/src/services/ecies/service.d.ts.map +1 -1
  94. package/src/services/ecies/service.js +6 -0
  95. package/src/services/ecies/service.js.map +1 -1
  96. package/src/services/ecies/single-recipient.d.ts +1 -1
  97. package/src/services/ecies/single-recipient.d.ts.map +1 -1
  98. package/src/services/ecies/single-recipient.js +1 -1
  99. package/src/services/ecies/single-recipient.js.map +1 -1
  100. package/src/services/encryption-stream.d.ts +3 -3
  101. package/src/services/encryption-stream.d.ts.map +1 -1
  102. package/src/services/encryption-stream.js +7 -7
  103. package/src/services/encryption-stream.js.map +1 -1
  104. package/src/services/index.d.ts +1 -0
  105. package/src/services/index.d.ts.map +1 -1
  106. package/src/services/index.js.map +1 -1
  107. package/src/services/multi-recipient-processor.d.ts +2 -2
  108. package/src/services/multi-recipient-processor.d.ts.map +1 -1
  109. package/src/services/multi-recipient-processor.js +4 -4
  110. package/src/services/multi-recipient-processor.js.map +1 -1
  111. package/src/services/voting.service.d.ts.map +1 -1
  112. package/src/services/voting.service.js +4 -4
  113. package/src/services/voting.service.js.map +1 -1
  114. package/src/test-mocks/mock-frontend-member.d.ts +1 -1
  115. package/src/test-mocks/mock-frontend-member.d.ts.map +1 -1
  116. package/src/test-mocks/mock-frontend-member.js +1 -1
  117. package/src/test-mocks/mock-frontend-member.js.map +1 -1
  118. package/src/types.d.ts +1 -1
  119. package/src/types.d.ts.map +1 -1
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Poll = void 0;
4
+ const audit_1 = require("./audit");
5
+ const security_1 = require("./security");
6
+ const types_1 = require("./types");
7
+ /**
8
+ * Poll aggregates encrypted votes using only public key.
9
+ * Cannot decrypt votes - requires separate Tallier with private key.
10
+ */
11
+ class Poll {
12
+ _id;
13
+ _choices;
14
+ _method;
15
+ _authority;
16
+ ___votingPublicKey;
17
+ _votes = new Map();
18
+ _receipts = new Map();
19
+ _createdAt;
20
+ _closedAt;
21
+ _maxWeight;
22
+ _auditLog;
23
+ constructor(id, choices, method, authority, votingPublicKey, maxWeight, allowInsecure) {
24
+ if (choices.length < 2)
25
+ throw new Error('Poll requires at least 2 choices');
26
+ if (!authority.votingPublicKey)
27
+ throw new Error('Authority must have voting keys');
28
+ security_1.VotingSecurityValidator.validate(method, { allowInsecure });
29
+ this._id = id;
30
+ this._choices = Object.freeze([...choices]);
31
+ this._method = method;
32
+ this._authority = authority;
33
+ this.___votingPublicKey = votingPublicKey;
34
+ this._maxWeight = maxWeight;
35
+ this._createdAt = Date.now();
36
+ this._auditLog = new audit_1.ImmutableAuditLog(authority);
37
+ // Record poll creation in audit log
38
+ this._auditLog.recordPollCreated(id, {
39
+ method,
40
+ choiceCount: choices.length,
41
+ maxWeight: maxWeight?.toString(),
42
+ });
43
+ }
44
+ get id() {
45
+ return this._id;
46
+ }
47
+ get choices() {
48
+ return this._choices;
49
+ }
50
+ get method() {
51
+ return this._method;
52
+ }
53
+ get isClosed() {
54
+ return this._closedAt !== undefined;
55
+ }
56
+ get voterCount() {
57
+ return this._receipts.size;
58
+ }
59
+ get createdAt() {
60
+ return this._createdAt;
61
+ }
62
+ get closedAt() {
63
+ return this._closedAt;
64
+ }
65
+ get auditLog() {
66
+ return this._auditLog;
67
+ }
68
+ /**
69
+ * Cast a vote - validates and encrypts based on method
70
+ */
71
+ vote(voter, vote) {
72
+ if (this.isClosed)
73
+ throw new Error('Poll is closed');
74
+ const voterId = this._toKey(voter.id);
75
+ if (this._receipts.has(voterId))
76
+ throw new Error('Already voted');
77
+ // Validate vote structure based on method
78
+ this._validateVote(vote);
79
+ // Store encrypted vote
80
+ this._votes.set(voterId, vote.encrypted);
81
+ // Generate receipt
82
+ const receipt = this._generateReceipt(voter);
83
+ this._receipts.set(voterId, receipt);
84
+ // Record vote in audit log
85
+ const voterIdHash = this._hashVoterId(voter.id);
86
+ this._auditLog.recordVoteCast(this._id, voterIdHash);
87
+ return receipt;
88
+ }
89
+ /**
90
+ * Verify a receipt is valid for this poll
91
+ */
92
+ verifyReceipt(voter, receipt) {
93
+ const voterId = this._toKey(voter.id);
94
+ const stored = this._receipts.get(voterId);
95
+ if (!stored)
96
+ return false;
97
+ // Verify signature
98
+ const data = this._receiptData(receipt);
99
+ return this._authority.verify(receipt.signature, data);
100
+ }
101
+ /**
102
+ * Close the poll - no more votes accepted
103
+ */
104
+ close() {
105
+ if (this.isClosed)
106
+ throw new Error('Already closed');
107
+ this._closedAt = Date.now();
108
+ // Record closure in audit log
109
+ this._auditLog.recordPollClosed(this._id, {
110
+ voterCount: this.voterCount,
111
+ closedAt: this._closedAt,
112
+ });
113
+ }
114
+ /**
115
+ * Get encrypted votes for tallying (read-only)
116
+ */
117
+ getEncryptedVotes() {
118
+ // Create a proxy that throws on mutation attempts
119
+ const frozenEntries = Array.from(this._votes.entries()).map(([key, value]) => [key, Object.freeze([...value])]);
120
+ const readonlyMap = new Map(frozenEntries);
121
+ return new Proxy(readonlyMap, {
122
+ get(target, prop) {
123
+ if (prop === 'set' || prop === 'delete' || prop === 'clear') {
124
+ throw new Error('Cannot modify readonly map');
125
+ }
126
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
127
+ const value = Reflect.get(target, prop);
128
+ // Bind methods to target to preserve 'this' context
129
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
130
+ return typeof value === 'function' ? value.bind(target) : value;
131
+ },
132
+ });
133
+ }
134
+ _validateVote(vote) {
135
+ switch (this._method) {
136
+ case types_1.VotingMethod.Plurality:
137
+ if (vote.choiceIndex === undefined)
138
+ throw new Error('Choice required');
139
+ if (vote.choiceIndex < 0 || vote.choiceIndex >= this._choices.length) {
140
+ throw new Error('Invalid choice');
141
+ }
142
+ break;
143
+ case types_1.VotingMethod.Approval:
144
+ if (!vote.choices?.length)
145
+ throw new Error('Choices required');
146
+ for (const c of vote.choices) {
147
+ if (c < 0 || c >= this._choices.length)
148
+ throw new Error('Invalid choice');
149
+ }
150
+ break;
151
+ case types_1.VotingMethod.Weighted:
152
+ if (vote.choiceIndex === undefined)
153
+ throw new Error('Choice required');
154
+ if (!vote.weight || vote.weight <= 0n)
155
+ throw new Error('Weight must be positive');
156
+ if (this._maxWeight && vote.weight > this._maxWeight) {
157
+ throw new Error('Weight exceeds maximum');
158
+ }
159
+ break;
160
+ case types_1.VotingMethod.Borda:
161
+ case types_1.VotingMethod.RankedChoice: {
162
+ if (!vote.rankings?.length)
163
+ throw new Error('Rankings required');
164
+ const seen = new Set();
165
+ for (const r of vote.rankings) {
166
+ if (r < 0 || r >= this._choices.length)
167
+ throw new Error('Invalid choice');
168
+ if (seen.has(r))
169
+ throw new Error('Duplicate ranking');
170
+ seen.add(r);
171
+ }
172
+ break;
173
+ }
174
+ }
175
+ if (!vote.encrypted?.length)
176
+ throw new Error('Encrypted data required');
177
+ }
178
+ _generateReceipt(voter) {
179
+ const nonce = new Uint8Array(16);
180
+ crypto.getRandomValues(nonce);
181
+ const receipt = {
182
+ voterId: voter.id,
183
+ pollId: this._id,
184
+ timestamp: Date.now(),
185
+ signature: new Uint8Array(0),
186
+ nonce,
187
+ };
188
+ const data = this._receiptData(receipt);
189
+ receipt.signature = this._authority.sign(data);
190
+ return receipt;
191
+ }
192
+ _receiptData(receipt) {
193
+ const parts = [
194
+ receipt.voterId,
195
+ receipt.pollId,
196
+ new Uint8Array(new BigUint64Array([BigInt(receipt.timestamp)]).buffer),
197
+ receipt.nonce,
198
+ ];
199
+ const totalLength = parts.reduce((sum, p) => sum + p.length, 0);
200
+ const result = new Uint8Array(totalLength);
201
+ let offset = 0;
202
+ for (const part of parts) {
203
+ result.set(part, offset);
204
+ offset += part.length;
205
+ }
206
+ return result;
207
+ }
208
+ _toKey(id) {
209
+ return Array.from(id)
210
+ .map((b) => b.toString(16).padStart(2, '0'))
211
+ .join('');
212
+ }
213
+ _hashVoterId(voterId) {
214
+ // Simple hash for voter ID anonymization
215
+ const encoder = new TextEncoder();
216
+ const data = encoder.encode(this._toKey(voterId));
217
+ const hash = new Uint8Array(32);
218
+ for (let i = 0; i < data.length && i < 32; i++) {
219
+ hash[i] = data[i];
220
+ }
221
+ return hash;
222
+ }
223
+ }
224
+ exports.Poll = Poll;
225
+ //# sourceMappingURL=poll-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll-core.js","sourceRoot":"","sources":["../../../../../../packages/digitaldefiance-ecies-lib/src/lib/voting/poll-core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,124 @@
1
+ import { KeyPair as PaillierKeyPair } from 'paillier-bigint';
2
+ import { Member } from '../../member';
3
+ import { ECIESService } from '../../services/ecies/service';
4
+ import { VotingService } from '../../services/voting.service';
5
+ export interface ECKeyPairBuffer {
6
+ privateKey: Uint8Array;
7
+ publicKey: Uint8Array;
8
+ }
9
+ /**
10
+ * Result of a voting poll with decrypted tallies
11
+ */
12
+ export interface VotingPollResults {
13
+ /** Total number of votes cast */
14
+ totalVotes: bigint;
15
+ /** Tallies for each choice */
16
+ tallies: bigint[];
17
+ /** Choice names */
18
+ choices: string[];
19
+ /** Percentage for each choice (0-100) */
20
+ percentages: number[];
21
+ /** Index of the winning choice */
22
+ winnerIndex: number;
23
+ /** Name of the winning choice */
24
+ winnerName: string;
25
+ /** Number of unique voters */
26
+ voterCount: number;
27
+ }
28
+ /**
29
+ * VotingPoll provides a high-level interface for conducting secure, verifiable polls
30
+ * using Paillier homomorphic encryption.
31
+ *
32
+ * Features:
33
+ * - Privacy-preserving vote aggregation (votes remain encrypted until tally)
34
+ * - Verifiable receipts for each voter
35
+ * - Multiple tallying and analysis methods
36
+ * - Ranked choice voting support
37
+ * - Weighted voting support
38
+ */
39
+ export declare class VotingPoll {
40
+ readonly choices: string[];
41
+ readonly votes: bigint[];
42
+ private readonly paillierKeyPair;
43
+ private readonly ecKeyPair;
44
+ private readonly eciesService;
45
+ readonly receipts: Map<string, Uint8Array>;
46
+ private readonly createdAt;
47
+ private closedAt?;
48
+ constructor(eciesService: ECIESService, choices: string[], paillierKeyPair: PaillierKeyPair, ecKeyPair: ECKeyPairBuffer, votes: bigint[]);
49
+ generateEncryptedReceipt(member: Member): Promise<Uint8Array>;
50
+ memberVoted(member: Member): boolean;
51
+ verifyReceipt(member: Member, encryptedReceipt: Uint8Array): Promise<boolean>;
52
+ vote(choiceIndex: number, member: Member): Promise<Uint8Array>;
53
+ voteWeighted(choiceIndex: number, weight: bigint, member: Member): Promise<Uint8Array>;
54
+ voteRanked(rankedChoices: number[], member: Member): Promise<Uint8Array>;
55
+ voteApproval(approvedChoices: number[], member: Member): Promise<Uint8Array>;
56
+ get tallies(): bigint[];
57
+ getTally(choiceIndex: number): bigint;
58
+ get leadingChoice(): string;
59
+ /**
60
+ * Get the index of the leading choice
61
+ */
62
+ get leadingChoiceIndex(): number;
63
+ /**
64
+ * Get complete poll results with percentages and winner
65
+ */
66
+ getResults(): VotingPollResults;
67
+ /**
68
+ * Get sorted results (descending by vote count)
69
+ */
70
+ getSortedResults(): Array<{
71
+ choice: string;
72
+ index: number;
73
+ tally: bigint;
74
+ percentage: number;
75
+ }>;
76
+ /**
77
+ * Check if there is a tie for first place
78
+ */
79
+ get hasTie(): boolean;
80
+ /**
81
+ * Get all choices tied for first place
82
+ */
83
+ get tiedChoices(): string[];
84
+ /**
85
+ * Get total number of unique voters
86
+ */
87
+ get voterCount(): number;
88
+ /**
89
+ * Get total encrypted votes (sum of all choice tallies)
90
+ * Note: This returns encrypted sum - decrypt with getTotalVotes()
91
+ */
92
+ get encryptedTotalVotes(): bigint;
93
+ /**
94
+ * Get total decrypted vote count
95
+ */
96
+ getTotalVotes(): bigint;
97
+ /**
98
+ * Close the poll (no more votes can be cast)
99
+ */
100
+ close(): void;
101
+ /**
102
+ * Check if poll is closed
103
+ */
104
+ get isClosed(): boolean;
105
+ /**
106
+ * Get poll creation timestamp
107
+ */
108
+ get createdAtTimestamp(): Date;
109
+ /**
110
+ * Get poll closed timestamp (undefined if not closed)
111
+ */
112
+ get closedAtTimestamp(): Date | undefined;
113
+ /**
114
+ * Get poll duration in milliseconds (undefined if not closed)
115
+ */
116
+ get durationMs(): number | undefined;
117
+ static newPoll(eciesService: ECIESService, choices: string[], paillierKeyPair: PaillierKeyPair, ecKeyPair: ECKeyPairBuffer): VotingPoll;
118
+ static newPollWithKeys(eciesService: ECIESService, votingService: VotingService, choices: string[]): Promise<{
119
+ poll: VotingPoll;
120
+ paillierKeyPair: PaillierKeyPair;
121
+ ecKeyPair: ECKeyPairBuffer;
122
+ }>;
123
+ }
124
+ //# sourceMappingURL=poll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.d.ts","sourceRoot":"","sources":["../../../../../../packages/digitaldefiance-ecies-lib/src/lib/voting/poll.ts"],"names":[],"mappings":"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"}