@digitaldefiance/ecies-lib 4.4.25 → 4.5.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.
@@ -0,0 +1,537 @@
1
+ "use strict";
2
+ /**
3
+ * Voting Service for browser/web environments
4
+ * Provides ECIES-to-Paillier key bridge for homomorphic encryption voting systems.
5
+ * Uses @noble/secp256k1 for ECDH (matching Node.js implementation).
6
+ */
7
+ Object.defineProperty(exports, "__esModule", { value: true });
8
+ exports.VotingService = exports.SecureDeterministicDRBG = exports.lcm = exports.gcd = exports.modInverse = exports.modPow = exports.millerRabinTest = void 0;
9
+ exports.hkdf = hkdf;
10
+ exports.generateDeterministicPrime = generateDeterministicPrime;
11
+ exports.generateDeterministicKeyPair = generateDeterministicKeyPair;
12
+ exports.deriveVotingKeysFromECDH = deriveVotingKeysFromECDH;
13
+ const secp256k1_js_1 = require("@noble/curves/secp256k1.js");
14
+ const voting_utils_1 = require("../voting-utils");
15
+ Object.defineProperty(exports, "millerRabinTest", { enumerable: true, get: function () { return voting_utils_1.millerRabinTest; } });
16
+ Object.defineProperty(exports, "modPow", { enumerable: true, get: function () { return voting_utils_1.modPow; } });
17
+ Object.defineProperty(exports, "modInverse", { enumerable: true, get: function () { return voting_utils_1.modInverse; } });
18
+ Object.defineProperty(exports, "gcd", { enumerable: true, get: function () { return voting_utils_1.gcd; } });
19
+ Object.defineProperty(exports, "lcm", { enumerable: true, get: function () { return voting_utils_1.lcm; } });
20
+ /**
21
+ * Decompress a secp256k1 compressed public key
22
+ * @param compressedKey - 33 bytes (1 byte prefix + 32 bytes x-coordinate)
23
+ * @returns 65 bytes uncompressed key (0x04 + x + y)
24
+ */
25
+ function decompressSecp256k1PublicKey(compressedKey) {
26
+ if (compressedKey.length !== 33) {
27
+ throw new Error(`Invalid compressed key length: expected 33 bytes, got ${compressedKey.length}`);
28
+ }
29
+ const prefix = compressedKey[0];
30
+ if (prefix !== 0x02 && prefix !== 0x03) {
31
+ throw new Error(`Invalid compressed key prefix: expected 0x02 or 0x03, got 0x${prefix.toString(16)}`);
32
+ }
33
+ // secp256k1 parameters
34
+ const p = 0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2fn;
35
+ const b = 7n;
36
+ // Extract x coordinate
37
+ const xBytes = compressedKey.slice(1);
38
+ let x = 0n;
39
+ for (let i = 0; i < xBytes.length; i++) {
40
+ x = (x << 8n) | BigInt(xBytes[i]);
41
+ }
42
+ // Calculate y² = x³ + 7 (mod p)
43
+ const ySquared = ((0, voting_utils_1.modPow)(x, 3n, p) + b) % p;
44
+ // Calculate y using Tonelli-Shanks algorithm (for p ≡ 3 mod 4, it's simpler)
45
+ // For secp256k1, p ≡ 3 mod 4, so y = ySquared^((p+1)/4) mod p
46
+ const y = (0, voting_utils_1.modPow)(ySquared, (p + 1n) / 4n, p);
47
+ // Choose the correct y based on prefix (even/odd)
48
+ const yIsEven = (y & 1n) === 0n;
49
+ const prefixIndicatesEven = prefix === 0x02;
50
+ const finalY = yIsEven === prefixIndicatesEven ? y : p - y;
51
+ // Construct uncompressed key: 0x04 + x + y
52
+ const uncompressed = new Uint8Array(65);
53
+ uncompressed[0] = 0x04;
54
+ // Write x coordinate
55
+ for (let i = 0; i < 32; i++) {
56
+ uncompressed[1 + i] = Number((x >> BigInt(8 * (31 - i))) & 0xffn);
57
+ }
58
+ // Write y coordinate
59
+ for (let i = 0; i < 32; i++) {
60
+ uncompressed[33 + i] = Number((finalY >> BigInt(8 * (31 - i))) & 0xffn);
61
+ }
62
+ return uncompressed;
63
+ }
64
+ /**
65
+ * HKDF implementation using Web Crypto API
66
+ *
67
+ * SECURITY: This is a cryptographically secure key derivation function.
68
+ * - Uses Web Crypto API for browser compatibility
69
+ * - Provides pseudorandomness indistinguishable from random
70
+ * - One-way: computationally infeasible to recover IKM from OKM
71
+ * - Domain separation via 'info' parameter
72
+ *
73
+ * @param secret - The input key material (IKM)
74
+ * @param salt - Optional salt value (non-secret random value)
75
+ * @param info - Context string for domain separation
76
+ * @param length - Length of output keying material in bytes
77
+ * @param hmacAlgorithm - HMAC algorithm to use (default: 'SHA-512')
78
+ * @returns Derived key material (OKM)
79
+ */
80
+ async function hkdf(secret, salt, info, length, hmacAlgorithm = 'SHA-512') {
81
+ // Import key material
82
+ const keyMaterial = await crypto.subtle.importKey('raw', secret, { name: 'HKDF' }, false, ['deriveBits']);
83
+ // Derive bits using HKDF
84
+ const derived = await crypto.subtle.deriveBits({
85
+ name: 'HKDF',
86
+ hash: hmacAlgorithm,
87
+ salt: salt || new Uint8Array(0),
88
+ info: new TextEncoder().encode(info),
89
+ }, keyMaterial, length * 8);
90
+ return new Uint8Array(derived);
91
+ }
92
+ /**
93
+ * Secure Deterministic Random Bit Generator using HMAC-DRBG (SP 800-90A)
94
+ * Web Crypto API version with proper async initialization
95
+ *
96
+ * SECURITY: NIST-approved deterministic random bit generator
97
+ * - Provides backtracking resistance
98
+ * - Provides prediction resistance
99
+ * - Cryptographically secure pseudorandom output
100
+ * - Uses async factory pattern for proper HMAC initialization
101
+ */
102
+ class SecureDeterministicDRBG {
103
+ v;
104
+ k;
105
+ hmacAlgorithm;
106
+ hashLength;
107
+ constructor(seed, hmacAlgorithm = 'SHA-512') {
108
+ this.hmacAlgorithm = hmacAlgorithm;
109
+ // SHA-512 = 64 bytes, SHA-256 = 32 bytes
110
+ this.hashLength = hmacAlgorithm === 'SHA-512' ? 64 : 32;
111
+ // Initialize V and K
112
+ this.v = new Uint8Array(this.hashLength).fill(0x01);
113
+ this.k = new Uint8Array(this.hashLength).fill(0x00);
114
+ }
115
+ /**
116
+ * Create and initialize a new DRBG instance
117
+ */
118
+ static async create(seed, hmacAlgorithm = 'SHA-512') {
119
+ const drbg = new SecureDeterministicDRBG(seed, hmacAlgorithm);
120
+ await drbg.update(seed);
121
+ return drbg;
122
+ }
123
+ async hmacAsync(key, data) {
124
+ const cryptoKey = await crypto.subtle.importKey('raw', key, { name: 'HMAC', hash: this.hmacAlgorithm }, false, ['sign']);
125
+ const signature = await crypto.subtle.sign('HMAC', cryptoKey, data);
126
+ return new Uint8Array(signature);
127
+ }
128
+ async update(providedData) {
129
+ // K = HMAC(K, V || 0x00 || provided_data)
130
+ let data = new Uint8Array(this.v.length + 1 + (providedData?.length || 0));
131
+ data.set(this.v, 0);
132
+ data[this.v.length] = 0x00;
133
+ if (providedData) {
134
+ data.set(providedData, this.v.length + 1);
135
+ }
136
+ this.k = await this.hmacAsync(this.k, data);
137
+ // V = HMAC(K, V)
138
+ this.v = await this.hmacAsync(this.k, this.v);
139
+ if (providedData) {
140
+ // K = HMAC(K, V || 0x01 || provided_data)
141
+ data = new Uint8Array(this.v.length + 1 + providedData.length);
142
+ data.set(this.v, 0);
143
+ data[this.v.length] = 0x01;
144
+ data.set(providedData, this.v.length + 1);
145
+ this.k = await this.hmacAsync(this.k, data);
146
+ // V = HMAC(K, V)
147
+ this.v = await this.hmacAsync(this.k, this.v);
148
+ }
149
+ }
150
+ async generate(numBytes) {
151
+ const result = new Uint8Array(numBytes);
152
+ let offset = 0;
153
+ while (offset < numBytes) {
154
+ this.v = await this.hmacAsync(this.k, this.v);
155
+ const copyLength = Math.min(this.v.length, numBytes - offset);
156
+ result.set(this.v.slice(0, copyLength), offset);
157
+ offset += copyLength;
158
+ }
159
+ await this.update();
160
+ return result;
161
+ }
162
+ }
163
+ exports.SecureDeterministicDRBG = SecureDeterministicDRBG;
164
+ /**
165
+ * Small prime sieve for quick composite elimination
166
+ */
167
+ const SMALL_PRIMES = [
168
+ 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97,
169
+ 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193,
170
+ 197, 199, 211, 223, 227, 229, 233, 239, 241, 251,
171
+ ];
172
+ /**
173
+ * Generate a deterministic prime number using DRBG (async web version)
174
+ */
175
+ async function generateDeterministicPrime(drbg, numBits, primeTestIterations = 256, maxAttempts = 10000) {
176
+ const numBytes = Math.ceil(numBits / 8);
177
+ const topBitMask = 1 << ((numBits - 1) % 8);
178
+ // Always perform exactly maxAttempts iterations for timing attack mitigation
179
+ let foundPrime = null;
180
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
181
+ // Continue checking even after finding prime to maintain constant timing
182
+ if (foundPrime !== null) {
183
+ // Perform dummy operations to maintain timing consistency
184
+ await drbg.generate(numBytes);
185
+ continue;
186
+ }
187
+ // Generate random bytes
188
+ const bytes = await drbg.generate(numBytes);
189
+ // Set top bit to ensure exact bit length
190
+ bytes[0] |= topBitMask;
191
+ // Set bottom bit to ensure odd number
192
+ bytes[bytes.length - 1] |= 1;
193
+ const candidate = BigInt('0x' + Array.from(bytes).map(b => b.toString(16).padStart(2, '0')).join(''));
194
+ // Quick check against small primes
195
+ let isComposite = false;
196
+ for (const smallPrime of SMALL_PRIMES) {
197
+ if (candidate % BigInt(smallPrime) === 0n && candidate !== BigInt(smallPrime)) {
198
+ isComposite = true;
199
+ break;
200
+ }
201
+ }
202
+ if (isComposite)
203
+ continue;
204
+ // Miller-Rabin primality test
205
+ if ((0, voting_utils_1.millerRabinTest)(candidate, primeTestIterations)) {
206
+ foundPrime = candidate;
207
+ }
208
+ }
209
+ if (foundPrime === null) {
210
+ throw new Error(`Failed to generate prime after ${maxAttempts} attempts`);
211
+ }
212
+ return foundPrime;
213
+ }
214
+ /**
215
+ * Generate a deterministic Paillier key pair from a seed (async web version)
216
+ */
217
+ async function generateDeterministicKeyPair(seed, bits = 3072, primeTestIterations = 256) {
218
+ // Validate inputs
219
+ if (!seed || seed.length < 32) {
220
+ throw new Error(`Seed must be at least 32 bytes, got ${seed?.length || 0}`);
221
+ }
222
+ if (bits < 2048) {
223
+ throw new Error(`Key size must be at least 2048 bits, got ${bits}`);
224
+ }
225
+ if (bits % 2 !== 0) {
226
+ throw new Error(`Key size must be even, got ${bits}`);
227
+ }
228
+ if (primeTestIterations < 64) {
229
+ throw new Error(`Must perform at least 64 Miller-Rabin iterations, got ${primeTestIterations}`);
230
+ }
231
+ // Load paillier-bigint dynamically (optional peer dependency)
232
+ let PublicKey;
233
+ let PrivateKey;
234
+ try {
235
+ const paillier = await import('paillier-bigint');
236
+ PublicKey = paillier.PublicKey;
237
+ PrivateKey = paillier.PrivateKey;
238
+ }
239
+ catch (error) {
240
+ throw new Error('paillier-bigint is required for voting functionality. Install it with: npm install paillier-bigint');
241
+ }
242
+ const drbg = await SecureDeterministicDRBG.create(seed);
243
+ // Generate two primes of half the key size
244
+ const primeBits = Math.floor(bits / 2);
245
+ const p = await generateDeterministicPrime(drbg, primeBits, primeTestIterations);
246
+ const q = await generateDeterministicPrime(drbg, primeBits, primeTestIterations);
247
+ // Calculate n = p * q
248
+ const n = p * q;
249
+ // Calculate lambda = lcm(p-1, q-1)
250
+ const lambda = (0, voting_utils_1.lcm)(p - 1n, q - 1n);
251
+ // For Paillier, g = n + 1 (simplest form)
252
+ const g = n + 1n;
253
+ // Calculate mu = (L(g^lambda mod n^2))^-1 mod n
254
+ // where L(x) = (x-1)/n
255
+ const nSquared = n * n;
256
+ const gLambda = (0, voting_utils_1.modPow)(g, lambda, nSquared);
257
+ const l = (gLambda - 1n) / n;
258
+ const mu = (0, voting_utils_1.modInverse)(l, n);
259
+ // Create key pair
260
+ const publicKey = new PublicKey(n, g);
261
+ const privateKey = new PrivateKey(lambda, mu, publicKey);
262
+ // Validate with test encryption/decryption
263
+ const testPlaintext = 42n;
264
+ const encrypted = publicKey.encrypt(testPlaintext);
265
+ const decrypted = privateKey.decrypt(encrypted);
266
+ if (decrypted !== testPlaintext) {
267
+ throw new Error('Key pair validation failed: test encryption/decryption mismatch');
268
+ }
269
+ return { publicKey, privateKey };
270
+ }
271
+ /**
272
+ * Derive Paillier voting keys from ECDH key pair (async web version)
273
+ *
274
+ * SECURITY PROPERTIES:
275
+ * - One-way: Computationally infeasible to recover ECDH keys from Paillier keys
276
+ * - Deterministic: Same ECDH keys always produce same Paillier keys
277
+ * - Collision-resistant: Different ECDH keys produce different Paillier keys
278
+ * - Domain-separated: Cryptographically bound to voting purpose via HKDF info
279
+ *
280
+ * SECURITY LEVEL: ~128 bits (equivalent to 3072-bit RSA)
281
+ * - ECDH: secp256k1 curve (~128-bit security, matches Node.js)
282
+ * - HKDF: SHA-512 (512-bit security against preimage)
283
+ * - Paillier: 3072-bit modulus (NIST recommended for 128-bit security)
284
+ *
285
+ * @param ecdhPrivKey - ECDH private key (32 bytes for secp256k1)
286
+ * @param ecdhPubKey - ECDH public key (33/64/65 bytes, compressed or uncompressed)
287
+ * @param options - Configuration options
288
+ * @returns Paillier key pair for voting operations
289
+ */
290
+ async function deriveVotingKeysFromECDH(ecdhPrivKey, ecdhPubKey, options = {}) {
291
+ const { curveName = 'secp256k1', // Use secp256k1 to match Node.js implementation
292
+ publicKeyMagic = 0x04, rawPublicKeyLength = 64, publicKeyLength = 65, hmacAlgorithm = 'SHA-512', hkdfInfo = 'PaillierPrimeGen', hkdfLength = 64, keypairBitLength = 3072, primeTestIterations = 256, } = options;
293
+ // Validate inputs with strict length checks
294
+ if (!ecdhPrivKey || ecdhPrivKey.length === 0) {
295
+ throw new Error('ECDH private key is required');
296
+ }
297
+ // Validate private key length (32 bytes for secp256k1)
298
+ if (ecdhPrivKey.length !== 32) {
299
+ throw new Error(`Invalid ECDH private key length: expected 32 bytes, got ${ecdhPrivKey.length}`);
300
+ }
301
+ if (!ecdhPubKey || ecdhPubKey.length === 0) {
302
+ throw new Error('ECDH public key is required');
303
+ }
304
+ // Handle both compressed (33 bytes) and uncompressed (65 bytes) public keys
305
+ // @noble/secp256k1 accepts both formats
306
+ let publicKeyForECDH;
307
+ if (ecdhPubKey.length === 33) {
308
+ // Compressed key - @noble/secp256k1 handles this natively
309
+ publicKeyForECDH = ecdhPubKey;
310
+ }
311
+ else if (ecdhPubKey.length === publicKeyLength && ecdhPubKey[0] === publicKeyMagic) {
312
+ // Already uncompressed with 0x04 prefix - @noble/secp256k1 handles this
313
+ publicKeyForECDH = ecdhPubKey;
314
+ }
315
+ else if (ecdhPubKey.length === rawPublicKeyLength) {
316
+ // Uncompressed without prefix - add it
317
+ publicKeyForECDH = new Uint8Array(publicKeyLength);
318
+ publicKeyForECDH[0] = publicKeyMagic;
319
+ publicKeyForECDH.set(ecdhPubKey, 1);
320
+ }
321
+ else {
322
+ throw new Error(`Invalid public key length: expected 33 (compressed), 64 (uncompressed raw), or 65 (uncompressed with prefix) bytes, got ${ecdhPubKey.length}`);
323
+ }
324
+ // Compute shared secret using @noble/secp256k1 (same as Node.js implementation)
325
+ const sharedSecret = secp256k1_js_1.secp256k1.getSharedSecret(ecdhPrivKey, publicKeyForECDH, false);
326
+ // Remove the 0x04 prefix from shared secret (getSharedSecret returns uncompressed point)
327
+ const sharedSecretBytes = sharedSecret.slice(1);
328
+ // Derive seed using HKDF
329
+ const seed = await hkdf(sharedSecret, null, hkdfInfo, hkdfLength, hmacAlgorithm);
330
+ // Generate deterministic key pair
331
+ return await generateDeterministicKeyPair(seed, keypairBitLength, primeTestIterations);
332
+ }
333
+ /**
334
+ * Voting service for deriving and managing Paillier voting keys from ECDH keys.
335
+ * Web/Browser version using @noble/secp256k1.
336
+ *
337
+ * SECURITY ARCHITECTURE:
338
+ * This service implements a novel but cryptographically sound bridge between
339
+ * ECDSA/ECDH keys and Paillier homomorphic encryption keys. The construction
340
+ * uses only proven cryptographic primitives:
341
+ *
342
+ * - ECDH (secp256k1): Shared secret computation via @noble/secp256k1
343
+ * - HKDF (RFC 5869): Cryptographically secure key derivation
344
+ * - HMAC-DRBG (NIST SP 800-90A): Deterministic random generation
345
+ * - Miller-Rabin (256 rounds): Primality testing (error < 2^-512)
346
+ * - Paillier (3072-bit): Homomorphic encryption
347
+ *
348
+ * SECURITY GUARANTEES:
349
+ * - 128-bit security level (equivalent to 3072-bit RSA)
350
+ * - One-way: Cannot recover ECDH keys from Paillier keys
351
+ * - Deterministic: Enables key recovery from same ECDH source
352
+ * - Collision-resistant: Birthday bound ~2^128 operations
353
+ * - Domain-separated: Cryptographic binding via HKDF info string
354
+ *
355
+ * THREAT MODEL:
356
+ * Protected against: factorization attacks, weak primes, small prime attacks
357
+ * Timing attacks: Mitigated via constant-time operations where possible
358
+ * Side-channels: Dependent on @noble/secp256k1 implementation
359
+ * Quantum: Vulnerable to Shor's algorithm (like all RSA-type systems)
360
+ *
361
+ * WEB-SPECIFIC CONSIDERATIONS:
362
+ * - All cryptographic operations are async
363
+ * - Uses secp256k1 curve (same as Node.js for cross-platform compatibility)
364
+ * - Uses @noble/secp256k1 library (already used for ECIES operations)
365
+ * - DRBG uses proper async factory pattern for HMAC initialization
366
+ *
367
+ * For detailed security analysis, see:
368
+ * docs/SECURITY_ANALYSIS_ECIES_PAILLIER_BRIDGE.md
369
+ */
370
+ class VotingService {
371
+ static instance;
372
+ /**
373
+ * Get singleton instance of VotingService
374
+ */
375
+ static getInstance() {
376
+ if (!VotingService.instance) {
377
+ VotingService.instance = new VotingService();
378
+ }
379
+ return VotingService.instance;
380
+ }
381
+ /**
382
+ * Derive Paillier voting keys from ECDH key pair.
383
+ *
384
+ * @param ecdhPrivKey - ECDH private key (32 bytes for secp256k1)
385
+ * @param ecdhPubKey - ECDH public key (33/64/65 bytes, compressed or uncompressed)
386
+ * @param options - Configuration options
387
+ * @returns Paillier key pair for voting operations
388
+ */
389
+ async deriveVotingKeysFromECDH(ecdhPrivKey, ecdhPubKey, options) {
390
+ return await deriveVotingKeysFromECDH(ecdhPrivKey, ecdhPubKey, options);
391
+ }
392
+ /**
393
+ * HKDF key derivation function (RFC 5869)
394
+ */
395
+ async hkdf(secret, salt, info, length, hmacAlgorithm) {
396
+ return await hkdf(secret, salt, info, length, hmacAlgorithm);
397
+ }
398
+ /**
399
+ * Miller-Rabin primality test
400
+ */
401
+ millerRabinTest(n, k) {
402
+ return (0, voting_utils_1.millerRabinTest)(n, k);
403
+ }
404
+ /**
405
+ * Modular exponentiation
406
+ */
407
+ modPow(base, exp, mod) {
408
+ return (0, voting_utils_1.modPow)(base, exp, mod);
409
+ }
410
+ /**
411
+ * Modular multiplicative inverse
412
+ */
413
+ modInverse(a, m) {
414
+ return (0, voting_utils_1.modInverse)(a, m);
415
+ }
416
+ /**
417
+ * Greatest common divisor
418
+ */
419
+ gcd(a, b) {
420
+ return (0, voting_utils_1.gcd)(a, b);
421
+ }
422
+ /**
423
+ * Least common multiple
424
+ */
425
+ lcm(a, b) {
426
+ return (0, voting_utils_1.lcm)(a, b);
427
+ }
428
+ /**
429
+ * Generate a deterministic prime using DRBG
430
+ */
431
+ async generateDeterministicPrime(drbg, numBits, primeTestIterations, maxAttempts) {
432
+ return await generateDeterministicPrime(drbg, numBits, primeTestIterations, maxAttempts);
433
+ }
434
+ /**
435
+ * Generate a deterministic Paillier key pair from seed
436
+ */
437
+ async generateDeterministicKeyPair(seed, bits, primeTestIterations) {
438
+ return await generateDeterministicKeyPair(seed, bits, primeTestIterations);
439
+ }
440
+ /**
441
+ * Create a secure deterministic random bit generator
442
+ */
443
+ async createDRBG(seed, hmacAlgorithm) {
444
+ return await SecureDeterministicDRBG.create(seed, hmacAlgorithm);
445
+ }
446
+ /**
447
+ * Serialize a Paillier public key to Uint8Array
448
+ *
449
+ * SECURITY: Public keys are safe to share. This serialization
450
+ * format is deterministic and preserves all key information.
451
+ */
452
+ votingPublicKeyToBuffer(publicKey) {
453
+ // Serialize n value as hex string
454
+ const nHex = publicKey.n.toString(16);
455
+ // Store length prefix (4 bytes) + hex string as UTF-8
456
+ const encoder = new TextEncoder();
457
+ const hexBytes = encoder.encode(nHex);
458
+ const result = new Uint8Array(4 + hexBytes.length);
459
+ const view = new DataView(result.buffer);
460
+ view.setUint32(0, hexBytes.length);
461
+ result.set(hexBytes, 4);
462
+ return result;
463
+ }
464
+ /**
465
+ * Deserialize a Paillier public key from Uint8Array
466
+ */
467
+ async bufferToVotingPublicKey(buffer) {
468
+ // Load PublicKey class
469
+ const { PublicKey } = await import('paillier-bigint');
470
+ // Read length prefix
471
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
472
+ const length = view.getUint32(0);
473
+ // Read hex string
474
+ const decoder = new TextDecoder();
475
+ const nHex = decoder.decode(buffer.slice(4, 4 + length));
476
+ const n = BigInt('0x' + nHex);
477
+ // g = n + 1 for simplified Paillier
478
+ return new PublicKey(n, n + 1n);
479
+ }
480
+ /**
481
+ * Serialize a Paillier private key to Uint8Array
482
+ *
483
+ * SECURITY WARNING: Private keys must be kept secret!
484
+ * - Only serialize for secure storage or transmission
485
+ * - Encrypt serialized keys before storing or transmitting
486
+ * - Consider using browser's IndexedDB with encryption
487
+ * - Never log or expose private keys in client-side code
488
+ */
489
+ votingPrivateKeyToBuffer(privateKey) {
490
+ // Serialize lambda and mu values
491
+ const lambdaHex = privateKey.lambda.toString(16);
492
+ const muHex = privateKey.mu.toString(16);
493
+ const encoder = new TextEncoder();
494
+ const lambdaBytes = encoder.encode(lambdaHex);
495
+ const muBytes = encoder.encode(muHex);
496
+ const result = new Uint8Array(8 + lambdaBytes.length + muBytes.length);
497
+ const view = new DataView(result.buffer);
498
+ view.setUint32(0, lambdaBytes.length);
499
+ result.set(lambdaBytes, 4);
500
+ view.setUint32(4 + lambdaBytes.length, muBytes.length);
501
+ result.set(muBytes, 8 + lambdaBytes.length);
502
+ return result;
503
+ }
504
+ /**
505
+ * Deserialize a Paillier private key from Uint8Array
506
+ */
507
+ async bufferToVotingPrivateKey(buffer, publicKey) {
508
+ // Load PrivateKey class
509
+ const { PrivateKey } = await import('paillier-bigint');
510
+ const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
511
+ const decoder = new TextDecoder();
512
+ // Read lambda
513
+ const lambdaLength = view.getUint32(0);
514
+ const lambdaHex = decoder.decode(buffer.slice(4, 4 + lambdaLength));
515
+ const lambda = BigInt('0x' + lambdaHex);
516
+ // Read mu
517
+ const muLength = view.getUint32(4 + lambdaLength);
518
+ const muHex = decoder.decode(buffer.slice(8 + lambdaLength, 8 + lambdaLength + muLength));
519
+ const mu = BigInt('0x' + muHex);
520
+ return new PrivateKey(lambda, mu, publicKey);
521
+ }
522
+ // Aliases for cross-platform compatibility tests
523
+ async serializePublicKey(publicKey) {
524
+ return this.votingPublicKeyToBuffer(publicKey);
525
+ }
526
+ async deserializePublicKey(buffer) {
527
+ return this.bufferToVotingPublicKey(buffer);
528
+ }
529
+ async serializePrivateKey(privateKey) {
530
+ return this.votingPrivateKeyToBuffer(privateKey);
531
+ }
532
+ async deserializePrivateKey(buffer, publicKey) {
533
+ return this.bufferToVotingPrivateKey(buffer, publicKey);
534
+ }
535
+ }
536
+ exports.VotingService = VotingService;
537
+ //# sourceMappingURL=voting.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voting.service.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-ecies-lib/src/services/voting.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Voting utilities for deriving Paillier keys from ECDH keys.
3
+ * This module provides cryptographic bridge functions to derive
4
+ * homomorphic encryption keys from ECDSA/ECDH key pairs.
5
+ *
6
+ * Note: Requires paillier-bigint as an optional peer dependency.
7
+ */
8
+ import type { KeyPair } from 'paillier-bigint';
9
+ /**
10
+ * HKDF implementation following RFC 5869
11
+ *
12
+ * SECURITY: This is a cryptographically secure key derivation function.
13
+ * - Platform-specific implementations (Web Crypto API for browser, Node crypto for server)
14
+ * - Provides pseudorandomness indistinguishable from random
15
+ * - One-way: computationally infeasible to recover IKM from OKM
16
+ * - Domain separation via 'info' parameter
17
+ *
18
+ * @param secret - The input key material
19
+ * @param salt - Optional salt value (non-secret random value)
20
+ * @param info - Optional context and application specific information
21
+ * @param length - Length of output keying material in bytes
22
+ * @param hmacAlgorithm - HMAC algorithm to use (default: 'sha512')
23
+ * @returns Derived key material
24
+ */
25
+ export declare function hkdf(secret: Uint8Array, salt: Uint8Array | null, info: string, length: number, hmacAlgorithm?: string): Uint8Array;
26
+ /**
27
+ * Miller-Rabin primality test with deterministic witnesses
28
+ *
29
+ * SECURITY: With k=256 rounds, probability of false positive is < 2^-512
30
+ * (more likely: cosmic ray bit flip or hardware failure)
31
+ *
32
+ * @param n - Number to test for primality
33
+ * @param k - Number of rounds (witnesses to test)
34
+ * @returns true if n is probably prime, false if definitely composite
35
+ */
36
+ export declare function millerRabinTest(n: bigint, k: number): boolean;
37
+ /**
38
+ * Modular exponentiation: (base^exp) mod mod
39
+ */
40
+ export declare function modPow(base: bigint, exp: bigint, mod: bigint): bigint;
41
+ /**
42
+ * Extended Euclidean algorithm to find modular multiplicative inverse
43
+ */
44
+ export declare function modInverse(a: bigint, m: bigint): bigint;
45
+ /**
46
+ * Greatest common divisor using Euclidean algorithm
47
+ */
48
+ export declare function gcd(a: bigint, b: bigint): bigint;
49
+ /**
50
+ * Least common multiple
51
+ */
52
+ export declare function lcm(a: bigint, b: bigint): bigint;
53
+ /**
54
+ * Derive Paillier voting keys from ECDH key pair.
55
+ * This is the core bridge function that connects ECDSA/ECDH keys
56
+ * to homomorphic encryption keys for secure voting systems.
57
+ *
58
+ * @param ecdhPrivKey - ECDH private key
59
+ * @param ecdhPubKey - ECDH public key (with or without 0x04 prefix)
60
+ * @param options - Configuration options
61
+ * @returns Paillier key pair for voting operations
62
+ */
63
+ export interface DeriveVotingKeysOptions {
64
+ /** Curve name (default: 'secp256k1') */
65
+ curveName?: string;
66
+ /** ECIES public key magic byte (default: 0x04) */
67
+ publicKeyMagic?: number;
68
+ /** Raw public key length without prefix (default: 64) */
69
+ rawPublicKeyLength?: number;
70
+ /** Public key length with prefix (default: 65) */
71
+ publicKeyLength?: number;
72
+ /** HMAC algorithm for HKDF (default: 'sha512') */
73
+ hmacAlgorithm?: string;
74
+ /** HKDF info string (default: 'PaillierPrimeGen') */
75
+ hkdfInfo?: string;
76
+ /** HKDF output length (default: 64) */
77
+ hkdfLength?: number;
78
+ /** Key pair bit length (default: 3072) */
79
+ keypairBitLength?: number;
80
+ /** Prime test iterations (default: 256) */
81
+ primeTestIterations?: number;
82
+ /** Max attempts to generate prime (default: 20000) */
83
+ maxPrimeAttempts?: number;
84
+ }
85
+ export declare function deriveVotingKeysFromECDH(ecdhPrivKey: Uint8Array, ecdhPubKey: Uint8Array, options?: DeriveVotingKeysOptions): KeyPair;
86
+ //# sourceMappingURL=voting-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voting-utils.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-ecies-lib/src/voting-utils.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAyB,MAAM,iBAAiB,CAAC;AAEtE;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,IAAI,CAClB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,GAAG,IAAI,EACvB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,aAAa,GAAE,MAAiB,GAC/B,UAAU,CAIZ;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAoC7D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAYrE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAoBvD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAUhD;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAEhD;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,uBAAuB;IACtC,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kDAAkD;IAClD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,kDAAkD;IAClD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,kDAAkD;IAClD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0CAA0C;IAC1C,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sDAAsD;IACtD,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,wBAAgB,wBAAwB,CACtC,WAAW,EAAE,UAAU,EACvB,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAIT"}