@digitaldefiance/ecies-lib 4.5.18 → 4.6.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 (69) hide show
  1. package/package.json +1 -1
  2. package/src/constants.d.ts +7 -0
  3. package/src/constants.d.ts.map +1 -1
  4. package/src/constants.js +25 -1
  5. package/src/constants.js.map +1 -1
  6. package/src/enumerations/index.d.ts +1 -0
  7. package/src/enumerations/index.d.ts.map +1 -1
  8. package/src/enumerations/index.js +1 -0
  9. package/src/enumerations/index.js.map +1 -1
  10. package/src/enumerations/voting-error-type.d.ts +37 -0
  11. package/src/enumerations/voting-error-type.d.ts.map +1 -0
  12. package/src/enumerations/voting-error-type.js +48 -0
  13. package/src/enumerations/voting-error-type.js.map +1 -0
  14. package/src/errors/index.d.ts +1 -0
  15. package/src/errors/index.d.ts.map +1 -1
  16. package/src/errors/index.js +1 -0
  17. package/src/errors/index.js.map +1 -1
  18. package/src/errors/voting.d.ts +16 -0
  19. package/src/errors/voting.d.ts.map +1 -0
  20. package/src/errors/voting.js +25 -0
  21. package/src/errors/voting.js.map +1 -0
  22. package/src/index.d.ts +2 -0
  23. package/src/index.d.ts.map +1 -1
  24. package/src/index.js +2 -0
  25. package/src/index.js.map +1 -1
  26. package/src/interfaces/constants.d.ts +2 -0
  27. package/src/interfaces/constants.d.ts.map +1 -1
  28. package/src/interfaces/ecies-library.d.ts +259 -0
  29. package/src/interfaces/ecies-library.d.ts.map +1 -0
  30. package/src/interfaces/ecies-library.js +9 -0
  31. package/src/interfaces/ecies-library.js.map +1 -0
  32. package/src/interfaces/index.d.ts +5 -0
  33. package/src/interfaces/index.d.ts.map +1 -1
  34. package/src/interfaces/index.js +5 -0
  35. package/src/interfaces/index.js.map +1 -1
  36. package/src/interfaces/isolated-keys.d.ts +83 -0
  37. package/src/interfaces/isolated-keys.d.ts.map +1 -0
  38. package/src/interfaces/isolated-keys.js +8 -0
  39. package/src/interfaces/isolated-keys.js.map +1 -0
  40. package/src/interfaces/member.d.ts +25 -21
  41. package/src/interfaces/member.d.ts.map +1 -1
  42. package/src/interfaces/platform-buffer.d.ts +9 -0
  43. package/src/interfaces/platform-buffer.d.ts.map +1 -0
  44. package/src/interfaces/platform-buffer.js +3 -0
  45. package/src/interfaces/platform-buffer.js.map +1 -0
  46. package/src/interfaces/voting-consts.d.ts +82 -0
  47. package/src/interfaces/voting-consts.d.ts.map +1 -0
  48. package/src/interfaces/voting-consts.js +3 -0
  49. package/src/interfaces/voting-consts.js.map +1 -0
  50. package/src/interfaces/voting-service.d.ts +131 -0
  51. package/src/interfaces/voting-service.d.ts.map +1 -0
  52. package/src/interfaces/voting-service.js +10 -0
  53. package/src/interfaces/voting-service.js.map +1 -0
  54. package/src/isolated-private.d.ts +67 -0
  55. package/src/isolated-private.d.ts.map +1 -0
  56. package/src/isolated-private.js +155 -0
  57. package/src/isolated-private.js.map +1 -0
  58. package/src/isolated-public.d.ts +138 -0
  59. package/src/isolated-public.d.ts.map +1 -0
  60. package/src/isolated-public.js +362 -0
  61. package/src/isolated-public.js.map +1 -0
  62. package/src/services/index.d.ts +1 -1
  63. package/src/services/index.d.ts.map +1 -1
  64. package/src/services/index.js +1 -11
  65. package/src/services/index.js.map +1 -1
  66. package/src/services/voting.service.d.ts +32 -2
  67. package/src/services/voting.service.d.ts.map +1 -1
  68. package/src/services/voting.service.js +230 -27
  69. package/src/services/voting.service.js.map +1 -1
@@ -0,0 +1,131 @@
1
+ /**
2
+ * Common interface for VotingService across ecies-lib and node-ecies-lib
3
+ *
4
+ * This interface defines the shared contract that both browser (Web Crypto)
5
+ * and Node.js (crypto module) implementations must adhere to, ensuring
6
+ * consistent behavior and cross-platform compatibility.
7
+ */
8
+ import type { KeyPair, PrivateKey, PublicKey } from 'paillier-bigint';
9
+ import type { IsolatedPrivateKey } from '../isolated-private';
10
+ import type { IsolatedPublicKey } from '../isolated-public';
11
+ import type { PlatformBuffer } from './platform-buffer';
12
+ /**
13
+ * Common interface for VotingService implementations
14
+ */
15
+ export interface IVotingService {
16
+ /**
17
+ * Serialize a base Paillier public key with magic/version/keyId
18
+ * Format: [magic:4][version:1][keyId:32][n_length:4][n:variable]
19
+ *
20
+ * @param publicKey - Paillier public key to serialize
21
+ * @returns Platform-specific buffer (Uint8Array or Buffer)
22
+ */
23
+ votingPublicKeyToBuffer(publicKey: PublicKey): PlatformBuffer | Promise<PlatformBuffer>;
24
+ /**
25
+ * Deserialize a base Paillier public key from buffer
26
+ * Format: [magic:4][version:1][keyId:32][n_length:4][n:variable]
27
+ *
28
+ * @param buffer - Serialized public key
29
+ * @returns Deserialized Paillier public key
30
+ */
31
+ bufferToVotingPublicKey(buffer: PlatformBuffer): Promise<PublicKey>;
32
+ /**
33
+ * Serialize a base Paillier private key with magic/version
34
+ * Format: [magic:4][version:1][lambda_length:4][lambda:variable][mu_length:4][mu:variable]
35
+ *
36
+ * @param privateKey - Paillier private key to serialize
37
+ * @returns Platform-specific buffer (Uint8Array or Buffer)
38
+ */
39
+ votingPrivateKeyToBuffer(privateKey: PrivateKey): PlatformBuffer;
40
+ /**
41
+ * Deserialize a base Paillier private key from buffer
42
+ * Format: [magic:4][version:1][lambda_length:4][lambda:variable][mu_length:4][mu:variable]
43
+ *
44
+ * @param buffer - Serialized private key
45
+ * @param publicKey - Corresponding public key
46
+ * @returns Deserialized Paillier private key
47
+ */
48
+ bufferToVotingPrivateKey(buffer: PlatformBuffer, publicKey: PublicKey): Promise<PrivateKey>;
49
+ /**
50
+ * Serialize an IsolatedPublicKey with magic/version/keyId/instanceId
51
+ * Format: [magic:4][version:1][keyId:32][instanceId:32][n_length:4][n:variable]
52
+ *
53
+ * @param publicKey - Isolated public key to serialize
54
+ * @returns Platform-specific buffer (Uint8Array or Buffer)
55
+ */
56
+ isolatedPublicKeyToBuffer(publicKey: IsolatedPublicKey): PlatformBuffer;
57
+ /**
58
+ * Deserialize an IsolatedPublicKey from buffer
59
+ * Format: [magic:4][version:1][keyId:32][instanceId:32][n_length:4][n:variable]
60
+ *
61
+ * @param buffer - Serialized isolated public key
62
+ * @returns Deserialized IsolatedPublicKey
63
+ */
64
+ bufferToIsolatedPublicKey(buffer: PlatformBuffer): Promise<IsolatedPublicKey>;
65
+ /**
66
+ * Serialize an IsolatedPrivateKey
67
+ * Uses same format as base private key
68
+ *
69
+ * @param privateKey - Isolated private key to serialize
70
+ * @returns Platform-specific buffer (Uint8Array or Buffer)
71
+ */
72
+ isolatedPrivateKeyToBuffer(privateKey: IsolatedPrivateKey): PlatformBuffer;
73
+ /**
74
+ * Deserialize an IsolatedPrivateKey from buffer
75
+ *
76
+ * @param buffer - Serialized isolated private key
77
+ * @param publicKey - Corresponding IsolatedPublicKey
78
+ * @returns Deserialized IsolatedPrivateKey
79
+ */
80
+ bufferToIsolatedPrivateKey(buffer: PlatformBuffer, publicKey: IsolatedPublicKey): Promise<IsolatedPrivateKey>;
81
+ /**
82
+ * Derive Paillier voting keys from ECDH key pair
83
+ *
84
+ * SECURITY: This is the proper way to generate voting keys - they must be
85
+ * derived from ECDH keys to bind them to user identity.
86
+ *
87
+ * @param ecdhPrivateKey - ECDH private key
88
+ * @param ecdhPublicKey - ECDH public key
89
+ * @param options - Optional derivation parameters
90
+ * @returns Paillier key pair
91
+ */
92
+ deriveVotingKeysFromECDH(ecdhPrivateKey: PlatformBuffer, ecdhPublicKey: PlatformBuffer, options?: Record<string, unknown>): Promise<KeyPair>;
93
+ /**
94
+ * Generate deterministic Paillier key pair from seed
95
+ *
96
+ * WARNING: For testing only! Production voting keys MUST be derived from
97
+ * ECDH keys using deriveVotingKeysFromECDH().
98
+ *
99
+ * @param seed - Random seed for deterministic generation
100
+ * @param bitLength - Key bit length (default: 3072)
101
+ * @param iterations - Prime test iterations (default: 256)
102
+ * @returns Paillier key pair
103
+ */
104
+ generateDeterministicKeyPair(seed: PlatformBuffer, bitLength?: number, iterations?: number): Promise<KeyPair>;
105
+ }
106
+ /**
107
+ * Extended interface for IsolatedPublicKey with async methods
108
+ * These are the actual methods used by the voting service implementations
109
+ */
110
+ export interface IIsolatedPublicKeyAsync {
111
+ readonly keyId: PlatformBuffer;
112
+ getKeyId(): PlatformBuffer;
113
+ getInstanceId(): PlatformBuffer;
114
+ updateInstanceId(): Promise<void>;
115
+ verifyKeyIdAsync(): Promise<void>;
116
+ encryptAsync(m: bigint): Promise<bigint>;
117
+ multiplyAsync(ciphertext: bigint, constant: bigint): Promise<bigint>;
118
+ additionAsync(a: bigint, b: bigint): Promise<bigint>;
119
+ extractInstanceId(ciphertext: bigint): Promise<PlatformBuffer>;
120
+ }
121
+ /**
122
+ * Extended interface for IsolatedPrivateKey with async methods
123
+ * These are the actual methods used by the voting service implementations
124
+ */
125
+ export interface IIsolatedPrivateKeyAsync {
126
+ decryptAsync(taggedCiphertext: bigint): Promise<bigint>;
127
+ getOriginalKeyId(): PlatformBuffer;
128
+ getOriginalInstanceId(): PlatformBuffer;
129
+ getOriginalPublicKey(): IIsolatedPublicKeyAsync;
130
+ }
131
+ //# sourceMappingURL=voting-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voting-service.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-ecies-lib/src/interfaces/voting-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAExD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,uBAAuB,CACrB,SAAS,EAAE,SAAS,GACnB,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAE5C;;;;;;OAMG;IACH,uBAAuB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAEpE;;;;;;OAMG;IACH,wBAAwB,CAAC,UAAU,EAAE,UAAU,GAAG,cAAc,CAAC;IAEjE;;;;;;;OAOG;IACH,wBAAwB,CACtB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,UAAU,CAAC,CAAC;IAEvB;;;;;;OAMG;IACH,yBAAyB,CAAC,SAAS,EAAE,iBAAiB,GAAG,cAAc,CAAC;IAExE;;;;;;OAMG;IACH,yBAAyB,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAE9E;;;;;;OAMG;IACH,0BAA0B,CAAC,UAAU,EAAE,kBAAkB,GAAG,cAAc,CAAC;IAE3E;;;;;;OAMG;IACH,0BAA0B,CACxB,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,iBAAiB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAE/B;;;;;;;;;;OAUG;IACH,wBAAwB,CACtB,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,cAAc,EAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,OAAO,CAAC,CAAC;IAEpB;;;;;;;;;;OAUG;IACH,4BAA4B,CAC1B,IAAI,EAAE,cAAc,EACpB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,OAAO,CAAC,CAAC;CACrB;AAED;;;GAGG;AACH,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,QAAQ,IAAI,cAAc,CAAC;IAC3B,aAAa,IAAI,cAAc,CAAC;IAChC,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACzC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrE,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrD,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAChE;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACxD,gBAAgB,IAAI,cAAc,CAAC;IACnC,qBAAqB,IAAI,cAAc,CAAC;IACxC,oBAAoB,IAAI,uBAAuB,CAAC;CACjD"}
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ /**
3
+ * Common interface for VotingService across ecies-lib and node-ecies-lib
4
+ *
5
+ * This interface defines the shared contract that both browser (Web Crypto)
6
+ * and Node.js (crypto module) implementations must adhere to, ensuring
7
+ * consistent behavior and cross-platform compatibility.
8
+ */
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ //# sourceMappingURL=voting-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"voting-service.js","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-ecies-lib/src/interfaces/voting-service.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG"}
@@ -0,0 +1,67 @@
1
+ import { PrivateKey } from 'paillier-bigint';
2
+ import { IIsolatedPrivateKey } from './interfaces/isolated-keys';
3
+ import { IsolatedPublicKey } from './isolated-public';
4
+ /**
5
+ * IsolatedPrivateKey extends Paillier PrivateKey with instance isolation validation.
6
+ *
7
+ * This class ensures that:
8
+ * - Decryption only works with ciphertexts encrypted by the matching IsolatedPublicKey instance
9
+ * - Instance ID verification prevents cross-instance decryption attacks
10
+ * - HMAC validation ensures ciphertext integrity
11
+ *
12
+ * The private key stores the original keyId and instanceId from construction time,
13
+ * and validates them before any decryption operation.
14
+ */
15
+ export declare class IsolatedPrivateKey extends PrivateKey implements IIsolatedPrivateKey<Uint8Array, 'async'> {
16
+ /**
17
+ * Original keyId from the IsolatedPublicKey at construction time
18
+ */
19
+ private readonly _originalKeyId;
20
+ /**
21
+ * Original instanceId from the IsolatedPublicKey at construction time
22
+ */
23
+ private readonly _originalInstanceId;
24
+ /**
25
+ * Reference to the original IsolatedPublicKey
26
+ */
27
+ private readonly _originalPublicKey;
28
+ constructor(lambda: bigint, mu: bigint, publicKey: IsolatedPublicKey);
29
+ /**
30
+ * Converts hex string to Uint8Array
31
+ */
32
+ private hexToUint8Array;
33
+ /**
34
+ * Converts Uint8Array to hex string
35
+ */
36
+ private uint8ArrayToHex;
37
+ /**
38
+ * Compares two Uint8Arrays for equality
39
+ */
40
+ private uint8ArrayEquals;
41
+ /**
42
+ * Decrypts a tagged ciphertext after validating instance ID and HMAC
43
+ */
44
+ decryptAsync(taggedCiphertext: bigint): Promise<bigint>;
45
+ /**
46
+ * Synchronous decrypt override (throws error - use decryptAsync instead)
47
+ */
48
+ decrypt(_taggedCiphertext: bigint): bigint;
49
+ /**
50
+ * Gets a copy of the original keyId
51
+ */
52
+ getOriginalKeyId(): Uint8Array;
53
+ /**
54
+ * Gets a copy of the original instanceId
55
+ */
56
+ getOriginalInstanceId(): Uint8Array;
57
+ /**
58
+ * Gets the original public key reference
59
+ */
60
+ getOriginalPublicKey(): IsolatedPublicKey;
61
+ /**
62
+ * Decrypts a tagged ciphertext after validating instance ID and HMAC
63
+ * Implements both sync and async interfaces
64
+ */
65
+ decryptIsolated(taggedCiphertext: bigint): Promise<bigint>;
66
+ }
67
+ //# sourceMappingURL=isolated-private.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isolated-private.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-ecies-lib/src/isolated-private.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,MAAM,iBAAiB,CAAC;AAIxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AAEtD;;;;;;;;;;GAUG;AACH,qBAAa,kBACX,SAAQ,UACR,YAAW,mBAAmB,CAAC,UAAU,EAAE,OAAO,CAAC;IAEnD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAa;IAE5C;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAa;IAEjD;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAoB;gBAE3C,MAAM,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB;IAepE;;OAEG;IACH,OAAO,CAAC,eAAe;IAWvB;;OAEG;IACH,OAAO,CAAC,eAAe;IAMvB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;OAEG;IACU,YAAY,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAiEpE;;OAEG;IACM,OAAO,CAAC,iBAAiB,EAAE,MAAM,GAAG,MAAM;IAInD;;OAEG;IACI,gBAAgB,IAAI,UAAU;IAIrC;;OAEG;IACI,qBAAqB,IAAI,UAAU;IAI1C;;OAEG;IACI,oBAAoB,IAAI,iBAAiB;IAIhD;;;OAGG;IACI,eAAe,CAAC,gBAAgB,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAGlE"}
@@ -0,0 +1,155 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IsolatedPrivateKey = void 0;
4
+ const paillier_bigint_1 = require("paillier-bigint");
5
+ const constants_1 = require("./constants");
6
+ const voting_error_type_1 = require("./enumerations/voting-error-type");
7
+ const voting_1 = require("./errors/voting");
8
+ const isolated_public_1 = require("./isolated-public");
9
+ /**
10
+ * IsolatedPrivateKey extends Paillier PrivateKey with instance isolation validation.
11
+ *
12
+ * This class ensures that:
13
+ * - Decryption only works with ciphertexts encrypted by the matching IsolatedPublicKey instance
14
+ * - Instance ID verification prevents cross-instance decryption attacks
15
+ * - HMAC validation ensures ciphertext integrity
16
+ *
17
+ * The private key stores the original keyId and instanceId from construction time,
18
+ * and validates them before any decryption operation.
19
+ */
20
+ class IsolatedPrivateKey extends paillier_bigint_1.PrivateKey {
21
+ /**
22
+ * Original keyId from the IsolatedPublicKey at construction time
23
+ */
24
+ _originalKeyId;
25
+ /**
26
+ * Original instanceId from the IsolatedPublicKey at construction time
27
+ */
28
+ _originalInstanceId;
29
+ /**
30
+ * Reference to the original IsolatedPublicKey
31
+ */
32
+ _originalPublicKey;
33
+ constructor(lambda, mu, publicKey) {
34
+ if (!isolated_public_1.IsolatedPublicKey.isIsolatedPublicKey(publicKey)) {
35
+ throw new voting_1.VotingError(voting_error_type_1.VotingErrorType.InvalidPublicKeyFormat);
36
+ }
37
+ // Create a base PublicKey instance for the parent constructor
38
+ const basePublicKey = new paillier_bigint_1.PublicKey(publicKey.n, publicKey.g);
39
+ super(lambda, mu, basePublicKey);
40
+ // Store the isolated public key for our own use
41
+ this._originalKeyId = publicKey.getKeyId();
42
+ this._originalInstanceId = publicKey.getInstanceId();
43
+ this._originalPublicKey = publicKey;
44
+ }
45
+ /**
46
+ * Converts hex string to Uint8Array
47
+ */
48
+ hexToUint8Array(hex) {
49
+ if (hex.length % 2 !== 0) {
50
+ hex = '0' + hex;
51
+ }
52
+ const bytes = new Uint8Array(hex.length / 2);
53
+ for (let i = 0; i < hex.length; i += 2) {
54
+ bytes[i / 2] = parseInt(hex.substr(i, 2), 16);
55
+ }
56
+ return bytes;
57
+ }
58
+ /**
59
+ * Converts Uint8Array to hex string
60
+ */
61
+ uint8ArrayToHex(bytes) {
62
+ return Array.from(bytes)
63
+ .map((b) => b.toString(16).padStart(2, '0'))
64
+ .join('');
65
+ }
66
+ /**
67
+ * Compares two Uint8Arrays for equality
68
+ */
69
+ uint8ArrayEquals(a, b) {
70
+ if (a.length !== b.length)
71
+ return false;
72
+ for (let i = 0; i < a.length; i++) {
73
+ if (a[i] !== b[i])
74
+ return false;
75
+ }
76
+ return true;
77
+ }
78
+ /**
79
+ * Decrypts a tagged ciphertext after validating instance ID and HMAC
80
+ */
81
+ async decryptAsync(taggedCiphertext) {
82
+ // First verify if we're using a recovered key by checking the public key instance
83
+ if (!isolated_public_1.IsolatedPublicKey.isIsolatedPublicKey(this._originalPublicKey)) {
84
+ throw new voting_1.VotingError(voting_error_type_1.VotingErrorType.InvalidPublicKeyFormat);
85
+ }
86
+ // Compare instance IDs before any ciphertext operations
87
+ const currentInstanceId = this._originalPublicKey.getInstanceId();
88
+ // This check must happen before any ciphertext operations
89
+ if (!this.uint8ArrayEquals(currentInstanceId, this._originalInstanceId)) {
90
+ throw new voting_1.VotingError(voting_error_type_1.VotingErrorType.InstanceIdMismatch);
91
+ }
92
+ // Now that we've verified the instance ID, we can proceed with ciphertext operations
93
+ try {
94
+ const hmacLength = 64;
95
+ const ciphertextString = taggedCiphertext.toString(constants_1.VOTING.KEY_RADIX);
96
+ const receivedHmac = ciphertextString.slice(-hmacLength);
97
+ const ciphertextHex = ciphertextString.slice(0, -hmacLength);
98
+ const ciphertextBigInt = BigInt(`0x${ciphertextHex}`);
99
+ // Create HMAC key from originalKeyId + originalInstanceId
100
+ const hmacKeyMaterial = new Uint8Array(this._originalKeyId.length + this._originalInstanceId.length);
101
+ hmacKeyMaterial.set(this._originalKeyId, 0);
102
+ hmacKeyMaterial.set(this._originalInstanceId, this._originalKeyId.length);
103
+ const hmacKey = await crypto.subtle.importKey('raw', hmacKeyMaterial, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
104
+ // Calculate expected HMAC
105
+ const ciphertextBytes = new TextEncoder().encode(ciphertextBigInt.toString(constants_1.VOTING.KEY_RADIX));
106
+ const signature = await crypto.subtle.sign('HMAC', hmacKey, ciphertextBytes);
107
+ const expectedHmac = this.uint8ArrayToHex(new Uint8Array(signature));
108
+ // Verify HMAC
109
+ if (receivedHmac !== expectedHmac) {
110
+ throw new voting_1.VotingError(voting_error_type_1.VotingErrorType.InvalidCiphertextHmac);
111
+ }
112
+ // Finally decrypt the ciphertext using the parent class implementation
113
+ return super.decrypt(ciphertextBigInt);
114
+ }
115
+ catch (error) {
116
+ if (error instanceof voting_1.VotingError) {
117
+ throw error;
118
+ }
119
+ throw new voting_1.VotingError(voting_error_type_1.VotingErrorType.InvalidPrivateKeyBufferFailedToParse);
120
+ }
121
+ }
122
+ /**
123
+ * Synchronous decrypt override (throws error - use decryptAsync instead)
124
+ */
125
+ decrypt(_taggedCiphertext) {
126
+ throw new voting_1.VotingError(voting_error_type_1.VotingErrorType.KeyPairValidationFailed);
127
+ }
128
+ /**
129
+ * Gets a copy of the original keyId
130
+ */
131
+ getOriginalKeyId() {
132
+ return new Uint8Array(this._originalKeyId);
133
+ }
134
+ /**
135
+ * Gets a copy of the original instanceId
136
+ */
137
+ getOriginalInstanceId() {
138
+ return new Uint8Array(this._originalInstanceId);
139
+ }
140
+ /**
141
+ * Gets the original public key reference
142
+ */
143
+ getOriginalPublicKey() {
144
+ return this._originalPublicKey;
145
+ }
146
+ /**
147
+ * Decrypts a tagged ciphertext after validating instance ID and HMAC
148
+ * Implements both sync and async interfaces
149
+ */
150
+ decryptIsolated(taggedCiphertext) {
151
+ return this.decryptAsync(taggedCiphertext);
152
+ }
153
+ }
154
+ exports.IsolatedPrivateKey = IsolatedPrivateKey;
155
+ //# sourceMappingURL=isolated-private.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isolated-private.js","sourceRoot":"","sources":["../../../../packages/digitaldefiance-ecies-lib/src/isolated-private.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,138 @@
1
+ import { PublicKey } from 'paillier-bigint';
2
+ import { IIsolatedPublicKey } from './interfaces/isolated-keys';
3
+ /**
4
+ * IsolatedPublicKey extends Paillier PublicKey with instance isolation capabilities.
5
+ *
6
+ * This class provides:
7
+ * - keyId: A deterministic SHA-256 hash of the public key 'n' value for verification
8
+ * - instanceId: A unique identifier per key instance to prevent cross-instance operations
9
+ * - HMAC-tagged ciphertexts that bind encrypted values to a specific key instance
10
+ *
11
+ * Instance isolation ensures that ciphertexts encrypted with one instance cannot be
12
+ * used with another instance, even if they share the same underlying key material.
13
+ * This is critical for voting systems where ballot tampering must be prevented.
14
+ */
15
+ export declare class IsolatedPublicKey extends PublicKey implements IIsolatedPublicKey<Uint8Array, 'async'> {
16
+ /**
17
+ * Type guard to check if a PublicKey is an IsolatedPublicKey
18
+ */
19
+ static isIsolatedPublicKey(key: PublicKey): key is IsolatedPublicKey;
20
+ /**
21
+ * Deterministic identifier derived from the public key (SHA-256 of 'n')
22
+ */
23
+ readonly keyId: Uint8Array;
24
+ /**
25
+ * Original instance ID generated at construction time
26
+ */
27
+ private readonly _originalInstanceId;
28
+ /**
29
+ * Current instance ID (can be updated via updateInstanceId())
30
+ */
31
+ private _currentInstanceId;
32
+ /**
33
+ * Unique salt used for instance ID generation
34
+ */
35
+ private readonly uniqueInstanceSalt;
36
+ /**
37
+ * Updates the current instance ID to a new random value.
38
+ * This invalidates all previously encrypted ciphertexts.
39
+ */
40
+ updateInstanceId(): Promise<void>;
41
+ /**
42
+ * Generates a deterministic instance ID from keyId, n, and a unique salt
43
+ */
44
+ private generateInstanceId;
45
+ /**
46
+ * Async SHA-256 hash using Web Crypto API
47
+ */
48
+ private sha256Async;
49
+ /**
50
+ * Converts hex string to Uint8Array
51
+ */
52
+ private hexToUint8Array;
53
+ /**
54
+ * Converts Uint8Array to hex string
55
+ */
56
+ private uint8ArrayToHex;
57
+ constructor(n: bigint, g: bigint, keyId: Uint8Array);
58
+ /**
59
+ * Static factory method to create IsolatedPublicKey asynchronously
60
+ */
61
+ static create(n: bigint, g: bigint, keyId: Uint8Array): Promise<IsolatedPublicKey>;
62
+ /**
63
+ * Static factory method to create IsolatedPublicKey from deserialized data
64
+ * Used when reconstructing a key from a buffer with a stored instanceId
65
+ */
66
+ static fromBuffer(n: bigint, g: bigint, keyId: Uint8Array, instanceId: Uint8Array): IsolatedPublicKey;
67
+ /**
68
+ * Returns a copy of the keyId
69
+ */
70
+ getKeyId(): Uint8Array;
71
+ /**
72
+ * Returns a copy of the current instance ID
73
+ */
74
+ getInstanceId(): Uint8Array;
75
+ /**
76
+ * Tags a ciphertext with an HMAC using keyId + instanceId
77
+ * Returns a new bigint with the HMAC appended
78
+ */
79
+ private tagCiphertext;
80
+ /**
81
+ * Extracts and validates the instance ID from a tagged ciphertext
82
+ * Returns the instance ID if valid, or zero-filled array if invalid
83
+ */
84
+ extractInstanceId(ciphertext: bigint): Promise<Uint8Array>;
85
+ /**
86
+ * Encrypts a message and tags it with instance HMAC
87
+ */
88
+ encryptAsync(m: bigint): Promise<bigint>;
89
+ /**
90
+ * Synchronous encrypt override (throws error - use encryptAsync instead)
91
+ */
92
+ encrypt(_m: bigint): bigint;
93
+ /**
94
+ * Multiplies a ciphertext by a constant, preserving instance HMAC
95
+ */
96
+ multiplyAsync(ciphertext: bigint, constant: bigint): Promise<bigint>;
97
+ /**
98
+ * Synchronous multiply override (throws error - use multiplyAsync instead)
99
+ */
100
+ multiply(_ciphertext: bigint, _constant: bigint): bigint;
101
+ /**
102
+ * Adds two ciphertexts, preserving instance HMAC
103
+ */
104
+ additionAsync(a: bigint, b: bigint): Promise<bigint>;
105
+ /**
106
+ * Synchronous addition override (throws error - use additionAsync instead)
107
+ */
108
+ addition(_a: bigint, _b: bigint): bigint;
109
+ /**
110
+ * Verifies that the keyId matches the SHA-256 hash of the public key 'n'
111
+ */
112
+ verifyKeyIdAsync(): Promise<void>;
113
+ /**
114
+ * Compares two Uint8Arrays for equality
115
+ */
116
+ private uint8ArrayEquals;
117
+ /**
118
+ * Encrypts a message and tags it with instance HMAC
119
+ * Implements both sync and async interfaces
120
+ */
121
+ encryptIsolated(m: bigint): Promise<bigint>;
122
+ /**
123
+ * Multiplies a ciphertext by a constant, preserving instance HMAC
124
+ * Implements both sync and async interfaces
125
+ */
126
+ multiplyIsolated(ciphertext: bigint, constant: bigint): Promise<bigint>;
127
+ /**
128
+ * Adds two ciphertexts, preserving instance HMAC
129
+ * Implements both sync and async interfaces
130
+ */
131
+ additionIsolated(a: bigint, b: bigint): Promise<bigint>;
132
+ /**
133
+ * Verifies that the keyId matches the SHA-256 hash of the public key 'n'
134
+ * Sync version for interface compatibility
135
+ */
136
+ verifyKeyId(): void;
137
+ }
138
+ //# sourceMappingURL=isolated-public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"isolated-public.d.ts","sourceRoot":"","sources":["../../../../packages/digitaldefiance-ecies-lib/src/isolated-public.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,qBAAa,iBACX,SAAQ,SACR,YAAW,kBAAkB,CAAC,UAAU,EAAE,OAAO,CAAC;IAElD;;OAEG;WACW,mBAAmB,CAAC,GAAG,EAAE,SAAS,GAAG,GAAG,IAAI,iBAAiB;IAI3E;;OAEG;IACH,SAAgB,KAAK,EAAE,UAAU,CAAC;IAElC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,CAAa;IAEjD;;OAEG;IACH,OAAO,CAAC,kBAAkB,CAAa;IAEvC;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAa;IAEhD;;;OAGG;IACU,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAU9C;;OAEG;YACW,kBAAkB;IAuBhC;;OAEG;YACW,WAAW;IAKzB;;OAEG;IACH,OAAO,CAAC,eAAe;IAWvB;;OAEG;IACH,OAAO,CAAC,eAAe;gBAMX,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU;IAiBnD;;OAEG;WACiB,MAAM,CACxB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,UAAU,GAChB,OAAO,CAAC,iBAAiB,CAAC;IA4C7B;;;OAGG;WACW,UAAU,CACtB,CAAC,EAAE,MAAM,EACT,CAAC,EAAE,MAAM,EACT,KAAK,EAAE,UAAU,EACjB,UAAU,EAAE,UAAU,GACrB,iBAAiB;IA8BpB;;OAEG;IACI,QAAQ,IAAI,UAAU;IAI7B;;OAEG;IACI,aAAa,IAAI,UAAU;IAIlC;;;OAGG;YACW,aAAa;IAoC3B;;;OAGG;IACU,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA4CvE;;OAEG;IACU,YAAY,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAMrD;;OAEG;IACM,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAIpC;;OAEG;IACU,aAAa,CACxB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAmBlB;;OAEG;IACM,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM;IAIjE;;OAEG;IACU,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBjE;;OAEG;IACM,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM;IAIjD;;OAEG;IACU,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC;IAc9C;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAQxB;;;OAGG;IACI,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAIlD;;;OAGG;IACI,gBAAgB,CACrB,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,MAAM,CAAC;IAIlB;;;OAGG;IACI,gBAAgB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAI9D;;;OAGG;IACI,WAAW,IAAI,IAAI;CAG3B"}