@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.
- package/package.json +9 -1
- package/src/index.d.ts +2 -0
- package/src/index.d.ts.map +1 -1
- package/src/index.js +1 -0
- package/src/index.js.map +1 -1
- package/src/interfaces/member.d.ts +7 -0
- package/src/interfaces/member.d.ts.map +1 -1
- package/src/member.d.ts +11 -0
- package/src/member.d.ts.map +1 -1
- package/src/member.js +29 -0
- package/src/member.js.map +1 -1
- package/src/services/aes-gcm.js +3 -3
- package/src/services/aes-gcm.js.map +1 -1
- package/src/services/index.d.ts +1 -0
- package/src/services/index.d.ts.map +1 -1
- package/src/services/index.js +3 -0
- package/src/services/index.js.map +1 -1
- package/src/services/voting.service.d.ts +196 -0
- package/src/services/voting.service.d.ts.map +1 -0
- package/src/services/voting.service.js +537 -0
- package/src/services/voting.service.js.map +1 -0
- package/src/voting-utils.d.ts +86 -0
- package/src/voting-utils.d.ts.map +1 -0
- package/src/voting-utils.js +148 -0
- package/src/voting-utils.js.map +1 -0
|
@@ -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"}
|