@digitaldefiance/node-ecies-lib 1.1.21 → 1.1.22

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 (211) hide show
  1. package/README.md +4 -0
  2. package/package.json +14 -35
  3. package/src/constants.ts +182 -0
  4. package/src/enumerations/index.ts +1 -0
  5. package/src/enumerations/pbkdf2-profile.ts +8 -0
  6. package/src/i18n/ecies-i18n-factory.ts +435 -0
  7. package/{dist/i18n/index.d.ts → src/i18n/index.ts} +0 -1
  8. package/{dist/index.d.ts → src/index.ts} +0 -1
  9. package/src/interfaces/authenticated-cipher.ts +9 -0
  10. package/src/interfaces/authenticated-decipher.ts +8 -0
  11. package/src/interfaces/checksum-config.ts +4 -0
  12. package/src/interfaces/checksum-consts.ts +13 -0
  13. package/src/interfaces/constants.ts +43 -0
  14. package/src/interfaces/ecies-consts.ts +99 -0
  15. package/src/interfaces/encryption-consts.ts +10 -0
  16. package/{dist/interfaces/index.d.ts → src/interfaces/index.ts} +0 -1
  17. package/src/interfaces/keypair-buffer-with-un-encrypted-private-key.ts +7 -0
  18. package/src/interfaces/keyring-consts.ts +5 -0
  19. package/src/interfaces/member-operational.ts +52 -0
  20. package/{dist/interfaces/member-with-mnemonic.d.ts → src/interfaces/member-with-mnemonic.ts} +3 -3
  21. package/{dist/interfaces/multi-encrypted-message.d.ts → src/interfaces/multi-encrypted-message.ts} +5 -5
  22. package/src/interfaces/multi-encrypted-parsed-header.ts +24 -0
  23. package/{dist/interfaces/pbkdf-profiles.d.ts → src/interfaces/pbkdf-profiles.ts} +2 -2
  24. package/src/interfaces/pbkdf2-result.ts +5 -0
  25. package/src/interfaces/signing-key-private-key-info.ts +12 -0
  26. package/{dist/interfaces/simple-keypair-buffer.d.ts → src/interfaces/simple-keypair-buffer.ts} +3 -3
  27. package/{dist/interfaces/simple-keypair.d.ts → src/interfaces/simple-keypair.ts} +3 -3
  28. package/src/interfaces/simple-public-key-only-buffer.ts +3 -0
  29. package/src/interfaces/simple-public-key-only.ts +3 -0
  30. package/src/interfaces/single-encrypted-parsed-header.ts +35 -0
  31. package/{dist/interfaces/wallet-seed.d.ts → src/interfaces/wallet-seed.ts} +3 -3
  32. package/src/interfaces/wrapped-key-consts.ts +6 -0
  33. package/src/member.ts +463 -0
  34. package/src/services/aes-gcm.ts +160 -0
  35. package/src/services/ecies/crypto-core.ts +213 -0
  36. package/src/services/ecies/file.ts +174 -0
  37. package/{dist/services/ecies/index.d.ts → src/services/ecies/index.ts} +0 -1
  38. package/src/services/ecies/multi-recipient.ts +583 -0
  39. package/src/services/ecies/service.ts +351 -0
  40. package/src/services/ecies/signature.ts +91 -0
  41. package/src/services/ecies/single-recipient.ts +676 -0
  42. package/src/services/ecies/utilities.ts +111 -0
  43. package/src/services/index.ts +3 -0
  44. package/src/services/pbkdf2.ts +307 -0
  45. package/{dist/types.d.ts → src/types.ts} +26 -9
  46. package/src/utils.ts +104 -0
  47. package/dist/constants.d.ts +0 -32
  48. package/dist/constants.d.ts.map +0 -1
  49. package/dist/constants.js +0 -137
  50. package/dist/constants.js.map +0 -1
  51. package/dist/enumerations/index.d.ts +0 -2
  52. package/dist/enumerations/index.d.ts.map +0 -1
  53. package/dist/enumerations/index.js +0 -18
  54. package/dist/enumerations/index.js.map +0 -1
  55. package/dist/enumerations/pbkdf2-profile.d.ts +0 -9
  56. package/dist/enumerations/pbkdf2-profile.d.ts.map +0 -1
  57. package/dist/enumerations/pbkdf2-profile.js +0 -13
  58. package/dist/enumerations/pbkdf2-profile.js.map +0 -1
  59. package/dist/i18n/ecies-i18n-factory.d.ts +0 -54
  60. package/dist/i18n/ecies-i18n-factory.d.ts.map +0 -1
  61. package/dist/i18n/ecies-i18n-factory.js +0 -333
  62. package/dist/i18n/ecies-i18n-factory.js.map +0 -1
  63. package/dist/i18n/index.d.ts.map +0 -1
  64. package/dist/i18n/index.js +0 -18
  65. package/dist/i18n/index.js.map +0 -1
  66. package/dist/index.d.ts.map +0 -1
  67. package/dist/index.js +0 -24
  68. package/dist/index.js.map +0 -1
  69. package/dist/interfaces/authenticated-cipher.d.ts +0 -10
  70. package/dist/interfaces/authenticated-cipher.d.ts.map +0 -1
  71. package/dist/interfaces/authenticated-cipher.js +0 -3
  72. package/dist/interfaces/authenticated-cipher.js.map +0 -1
  73. package/dist/interfaces/authenticated-decipher.d.ts +0 -9
  74. package/dist/interfaces/authenticated-decipher.d.ts.map +0 -1
  75. package/dist/interfaces/authenticated-decipher.js +0 -3
  76. package/dist/interfaces/authenticated-decipher.js.map +0 -1
  77. package/dist/interfaces/checksum-config.d.ts +0 -5
  78. package/dist/interfaces/checksum-config.d.ts.map +0 -1
  79. package/dist/interfaces/checksum-config.js +0 -3
  80. package/dist/interfaces/checksum-config.js.map +0 -1
  81. package/dist/interfaces/checksum-consts.d.ts +0 -11
  82. package/dist/interfaces/checksum-consts.d.ts.map +0 -1
  83. package/dist/interfaces/checksum-consts.js +0 -3
  84. package/dist/interfaces/checksum-consts.js.map +0 -1
  85. package/dist/interfaces/constants.d.ts +0 -43
  86. package/dist/interfaces/constants.d.ts.map +0 -1
  87. package/dist/interfaces/constants.js +0 -3
  88. package/dist/interfaces/constants.js.map +0 -1
  89. package/dist/interfaces/ecies-consts.d.ts +0 -88
  90. package/dist/interfaces/ecies-consts.d.ts.map +0 -1
  91. package/dist/interfaces/ecies-consts.js +0 -3
  92. package/dist/interfaces/ecies-consts.js.map +0 -1
  93. package/dist/interfaces/encryption-consts.d.ts +0 -11
  94. package/dist/interfaces/encryption-consts.d.ts.map +0 -1
  95. package/dist/interfaces/encryption-consts.js +0 -3
  96. package/dist/interfaces/encryption-consts.js.map +0 -1
  97. package/dist/interfaces/index.d.ts.map +0 -1
  98. package/dist/interfaces/index.js +0 -34
  99. package/dist/interfaces/index.js.map +0 -1
  100. package/dist/interfaces/keypair-buffer-with-un-encrypted-private-key.d.ts +0 -6
  101. package/dist/interfaces/keypair-buffer-with-un-encrypted-private-key.d.ts.map +0 -1
  102. package/dist/interfaces/keypair-buffer-with-un-encrypted-private-key.js +0 -3
  103. package/dist/interfaces/keypair-buffer-with-un-encrypted-private-key.js.map +0 -1
  104. package/dist/interfaces/keyring-consts.d.ts +0 -6
  105. package/dist/interfaces/keyring-consts.d.ts.map +0 -1
  106. package/dist/interfaces/keyring-consts.js +0 -3
  107. package/dist/interfaces/keyring-consts.js.map +0 -1
  108. package/dist/interfaces/member-operational.d.ts +0 -36
  109. package/dist/interfaces/member-operational.d.ts.map +0 -1
  110. package/dist/interfaces/member-operational.js +0 -3
  111. package/dist/interfaces/member-operational.js.map +0 -1
  112. package/dist/interfaces/member-with-mnemonic.d.ts.map +0 -1
  113. package/dist/interfaces/member-with-mnemonic.js +0 -3
  114. package/dist/interfaces/member-with-mnemonic.js.map +0 -1
  115. package/dist/interfaces/multi-encrypted-message.d.ts.map +0 -1
  116. package/dist/interfaces/multi-encrypted-message.js +0 -3
  117. package/dist/interfaces/multi-encrypted-message.js.map +0 -1
  118. package/dist/interfaces/multi-encrypted-parsed-header.d.ts +0 -24
  119. package/dist/interfaces/multi-encrypted-parsed-header.d.ts.map +0 -1
  120. package/dist/interfaces/multi-encrypted-parsed-header.js +0 -3
  121. package/dist/interfaces/multi-encrypted-parsed-header.js.map +0 -1
  122. package/dist/interfaces/pbkdf-profiles.d.ts.map +0 -1
  123. package/dist/interfaces/pbkdf-profiles.js +0 -3
  124. package/dist/interfaces/pbkdf-profiles.js.map +0 -1
  125. package/dist/interfaces/pbkdf2-result.d.ts +0 -6
  126. package/dist/interfaces/pbkdf2-result.d.ts.map +0 -1
  127. package/dist/interfaces/pbkdf2-result.js +0 -3
  128. package/dist/interfaces/pbkdf2-result.js.map +0 -1
  129. package/dist/interfaces/signing-key-private-key-info.d.ts +0 -11
  130. package/dist/interfaces/signing-key-private-key-info.d.ts.map +0 -1
  131. package/dist/interfaces/signing-key-private-key-info.js +0 -3
  132. package/dist/interfaces/signing-key-private-key-info.js.map +0 -1
  133. package/dist/interfaces/simple-keypair-buffer.d.ts.map +0 -1
  134. package/dist/interfaces/simple-keypair-buffer.js +0 -3
  135. package/dist/interfaces/simple-keypair-buffer.js.map +0 -1
  136. package/dist/interfaces/simple-keypair.d.ts.map +0 -1
  137. package/dist/interfaces/simple-keypair.js +0 -3
  138. package/dist/interfaces/simple-keypair.js.map +0 -1
  139. package/dist/interfaces/simple-public-key-only-buffer.d.ts +0 -4
  140. package/dist/interfaces/simple-public-key-only-buffer.d.ts.map +0 -1
  141. package/dist/interfaces/simple-public-key-only-buffer.js +0 -3
  142. package/dist/interfaces/simple-public-key-only-buffer.js.map +0 -1
  143. package/dist/interfaces/simple-public-key-only.d.ts +0 -4
  144. package/dist/interfaces/simple-public-key-only.d.ts.map +0 -1
  145. package/dist/interfaces/simple-public-key-only.js +0 -3
  146. package/dist/interfaces/simple-public-key-only.js.map +0 -1
  147. package/dist/interfaces/single-encrypted-parsed-header.d.ts +0 -35
  148. package/dist/interfaces/single-encrypted-parsed-header.d.ts.map +0 -1
  149. package/dist/interfaces/single-encrypted-parsed-header.js +0 -3
  150. package/dist/interfaces/single-encrypted-parsed-header.js.map +0 -1
  151. package/dist/interfaces/wallet-seed.d.ts.map +0 -1
  152. package/dist/interfaces/wallet-seed.js +0 -3
  153. package/dist/interfaces/wallet-seed.js.map +0 -1
  154. package/dist/interfaces/wrapped-key-consts.d.ts +0 -7
  155. package/dist/interfaces/wrapped-key-consts.d.ts.map +0 -1
  156. package/dist/interfaces/wrapped-key-consts.js +0 -3
  157. package/dist/interfaces/wrapped-key-consts.js.map +0 -1
  158. package/dist/member.d.ts +0 -74
  159. package/dist/member.d.ts.map +0 -1
  160. package/dist/member.js +0 -273
  161. package/dist/member.js.map +0 -1
  162. package/dist/services/aes-gcm.d.ts +0 -66
  163. package/dist/services/aes-gcm.d.ts.map +0 -1
  164. package/dist/services/aes-gcm.js +0 -115
  165. package/dist/services/aes-gcm.js.map +0 -1
  166. package/dist/services/ecies/crypto-core.d.ts +0 -83
  167. package/dist/services/ecies/crypto-core.d.ts.map +0 -1
  168. package/dist/services/ecies/crypto-core.js +0 -166
  169. package/dist/services/ecies/crypto-core.js.map +0 -1
  170. package/dist/services/ecies/file.d.ts +0 -30
  171. package/dist/services/ecies/file.d.ts.map +0 -1
  172. package/dist/services/ecies/file.js +0 -144
  173. package/dist/services/ecies/file.js.map +0 -1
  174. package/dist/services/ecies/index.d.ts.map +0 -1
  175. package/dist/services/ecies/index.js +0 -24
  176. package/dist/services/ecies/index.js.map +0 -1
  177. package/dist/services/ecies/multi-recipient.d.ts +0 -82
  178. package/dist/services/ecies/multi-recipient.d.ts.map +0 -1
  179. package/dist/services/ecies/multi-recipient.js +0 -360
  180. package/dist/services/ecies/multi-recipient.js.map +0 -1
  181. package/dist/services/ecies/service.d.ts +0 -70
  182. package/dist/services/ecies/service.d.ts.map +0 -1
  183. package/dist/services/ecies/service.js +0 -167
  184. package/dist/services/ecies/service.js.map +0 -1
  185. package/dist/services/ecies/signature.d.ts +0 -38
  186. package/dist/services/ecies/signature.d.ts.map +0 -1
  187. package/dist/services/ecies/signature.js +0 -69
  188. package/dist/services/ecies/signature.js.map +0 -1
  189. package/dist/services/ecies/single-recipient.d.ts +0 -85
  190. package/dist/services/ecies/single-recipient.d.ts.map +0 -1
  191. package/dist/services/ecies/single-recipient.js +0 -399
  192. package/dist/services/ecies/single-recipient.js.map +0 -1
  193. package/dist/services/ecies/utilities.d.ts +0 -22
  194. package/dist/services/ecies/utilities.d.ts.map +0 -1
  195. package/dist/services/ecies/utilities.js +0 -75
  196. package/dist/services/ecies/utilities.js.map +0 -1
  197. package/dist/services/index.d.ts +0 -4
  198. package/dist/services/index.d.ts.map +0 -1
  199. package/dist/services/index.js +0 -20
  200. package/dist/services/index.js.map +0 -1
  201. package/dist/services/pbkdf2.d.ts +0 -106
  202. package/dist/services/pbkdf2.d.ts.map +0 -1
  203. package/dist/services/pbkdf2.js +0 -195
  204. package/dist/services/pbkdf2.js.map +0 -1
  205. package/dist/types.d.ts.map +0 -1
  206. package/dist/types.js +0 -3
  207. package/dist/types.js.map +0 -1
  208. package/dist/utils.d.ts +0 -11
  209. package/dist/utils.d.ts.map +0 -1
  210. package/dist/utils.js +0 -82
  211. package/dist/utils.js.map +0 -1
@@ -0,0 +1,160 @@
1
+ import { createCipheriv, createDecipheriv, randomBytes } from 'crypto';
2
+ import { CipherGCMTypes } from 'crypto';
3
+ import { IConstants } from '../interfaces/constants';
4
+ import { getEciesPluginI18nEngine, NodeEciesComponentId, NodeEciesStringKey } from '../i18n';
5
+ import { Constants } from '../constants';
6
+
7
+ export class AESGCMService {
8
+ private readonly algorithmName: string;
9
+ private readonly mode: string;
10
+ private readonly keyBits: number;
11
+ private readonly ivSize: number;
12
+ private readonly keyringAlgorithmConfiguration: CipherGCMTypes;
13
+
14
+ constructor(constants: IConstants = Constants) {
15
+ this.algorithmName = constants.KEYRING.ALGORITHM;
16
+ this.mode = constants.KEYRING.MODE;
17
+ this.keyBits = constants.KEYRING.KEY_BITS;
18
+ this.ivSize = constants.WRAPPED_KEY.IV_SIZE;
19
+ this.keyringAlgorithmConfiguration = constants.KEYRING_ALGORITHM_CONFIGURATION;
20
+ }
21
+
22
+ public get ALGORITHM_NAME(): string {
23
+ return this.algorithmName;
24
+ }
25
+
26
+ public get MODE(): string {
27
+ return this.mode;
28
+ }
29
+
30
+ public get KEY_BITS(): number {
31
+ return this.keyBits;
32
+ }
33
+
34
+ /**
35
+ * Encrypt data using AES-GCM
36
+ * @param data Data to encrypt
37
+ * @param key Key to use for encryption (must be 16, 24 or 32 bytes for AES)
38
+ * @param authTag Whether to return separate auth tag
39
+ * @returns Encrypted data with IV and optional separate auth tag
40
+ */
41
+ public encrypt(
42
+ data: Buffer,
43
+ key: Buffer,
44
+ authTag: boolean = false,
45
+ ): { encrypted: Buffer; iv: Buffer; tag?: Buffer } {
46
+ const iv = randomBytes(this.ivSize);
47
+ const cipher = createCipheriv(this.keyringAlgorithmConfiguration, key, iv);
48
+
49
+ const encrypted = Buffer.concat([cipher.update(data), cipher.final()]);
50
+ const tag = cipher.getAuthTag();
51
+
52
+ if (!authTag) {
53
+ const encryptedWithTag = Buffer.concat([encrypted, tag]);
54
+ return { encrypted: encryptedWithTag, iv: iv };
55
+ }
56
+
57
+ return {
58
+ encrypted: encrypted,
59
+ iv: iv,
60
+ tag: tag,
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Combine encrypted data and auth tag into a single Buffer
66
+ * @param encryptedData The encrypted data
67
+ * @param authTag The authentication tag
68
+ * @returns The combined Buffer
69
+ */
70
+ public combineEncryptedDataAndTag(
71
+ encryptedData: Buffer,
72
+ authTag: Buffer,
73
+ ): Buffer {
74
+ return Buffer.concat([encryptedData, authTag]);
75
+ }
76
+
77
+ /**
78
+ * Combine IV and encrypted data (with optional auth tag) into a single Buffer
79
+ * @param iv The initialization vector
80
+ * @param encryptedDataWithTag The encrypted data with auth tag already appended (if applicable)
81
+ * @returns The combined Buffer
82
+ */
83
+ public combineIvAndEncryptedData(
84
+ iv: Buffer,
85
+ encryptedDataWithTag: Buffer,
86
+ ): Buffer {
87
+ return Buffer.concat([iv, encryptedDataWithTag]);
88
+ }
89
+
90
+ /**
91
+ * Combine IV, encrypted data and auth tag into a single Buffer
92
+ * @param iv The initialization vector
93
+ * @param encryptedData The encrypted data
94
+ * @param authTag The authentication tag
95
+ * @returns The combined Buffer
96
+ */
97
+ public combineIvTagAndEncryptedData(
98
+ iv: Buffer,
99
+ encryptedData: Buffer,
100
+ authTag: Buffer,
101
+ ): Buffer {
102
+ const encryptedWithTag = this.combineEncryptedDataAndTag(
103
+ encryptedData,
104
+ authTag,
105
+ );
106
+ return this.combineIvAndEncryptedData(iv, encryptedWithTag);
107
+ }
108
+
109
+ /**
110
+ * Split combined encrypted data back into its components
111
+ * @param combinedData The combined data containing IV, encrypted data, and optionally auth tag
112
+ * @param hasAuthTag Whether the combined data includes an authentication tag
113
+ * @returns Object containing the split components
114
+ */
115
+ public splitEncryptedData(
116
+ combinedData: Buffer,
117
+ hasAuthTag: boolean = true,
118
+ ): { iv: Buffer; encryptedDataWithTag: Buffer } {
119
+ const ivLength = this.ivSize;
120
+ const minLength = ivLength + (hasAuthTag ? 16 : 0);
121
+
122
+ if (combinedData.length < minLength) {
123
+ const pluginEngine = getEciesPluginI18nEngine();
124
+
125
+ throw new Error(
126
+ pluginEngine.translate(NodeEciesComponentId, NodeEciesStringKey.Error_CombinedDataTooShort),
127
+ );
128
+ }
129
+
130
+ const iv = combinedData.subarray(0, ivLength);
131
+ const encryptedDataWithTag = combinedData.subarray(ivLength);
132
+
133
+ return { iv, encryptedDataWithTag };
134
+ }
135
+
136
+ /**
137
+ * Decrypt data using AES-GCM
138
+ * @param iv The initialization vector
139
+ * @param encryptedData Data to decrypt (with auth tag appended)
140
+ * @param key Key to use for decryption (must be 16, 24 or 32 bytes for AES)
141
+ * @param authTag Whether the encrypted data includes an authentication tag
142
+ * @returns Decrypted data
143
+ */
144
+ public decrypt(
145
+ iv: Buffer,
146
+ encryptedData: Buffer,
147
+ key: Buffer,
148
+ authTag: boolean = false,
149
+ ): Buffer {
150
+ const decipher = createDecipheriv(this.keyringAlgorithmConfiguration, key, iv);
151
+
152
+ const tagLength = 16;
153
+ const tag = encryptedData.subarray(-tagLength);
154
+ const ciphertext = encryptedData.subarray(0, -tagLength);
155
+
156
+ decipher.setAuthTag(tag);
157
+
158
+ return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
159
+ }
160
+ }
@@ -0,0 +1,213 @@
1
+ import {
2
+ ECIESError,
3
+ ECIESErrorTypeEnum,
4
+ IECIESConfig,
5
+ IECIESConstants,
6
+ SecureBuffer,
7
+ SecureString,
8
+ } from '@digitaldefiance/ecies-lib';
9
+ import { hdkey, Wallet } from '@ethereumjs/wallet';
10
+ import { generateMnemonic, mnemonicToSeedSync, validateMnemonic } from 'bip39';
11
+ import { secp256k1 } from 'ethereum-cryptography/secp256k1.js';
12
+ import { createEciesTranslationEngine, getEciesPluginI18nEngine, NodeEciesComponentId, NodeEciesStringKey } from '../../i18n/ecies-i18n-factory';
13
+ import { ISimpleKeyPairBuffer } from '../../interfaces/simple-keypair-buffer';
14
+ import { IWalletSeed } from '../../interfaces/wallet-seed';
15
+ import { Constants } from '../../constants';
16
+
17
+ /**
18
+ * Core encryption and decryption functions for ECIES
19
+ * Includes coverage for simple and single modes, does not cover multiple mode which is in a separate module
20
+ */
21
+ export class EciesCryptoCore {
22
+ protected readonly _config: IECIESConfig;
23
+ protected readonly _consts: IECIESConstants;
24
+ public get config(): IECIESConfig {
25
+ return this._config;
26
+ }
27
+
28
+ public get consts(): IECIESConstants {
29
+ return this._consts;
30
+ }
31
+
32
+ constructor(config: IECIESConfig, eciesParams: IECIESConstants = Constants.ECIES) {
33
+ this._config = config;
34
+ this._consts = eciesParams;
35
+ }
36
+
37
+ /**
38
+ * Validates and normalizes a public key for ECIES operations
39
+ * @param publicKey The public key to normalize
40
+ * @returns Properly formatted public key
41
+ */
42
+ public normalizePublicKey(publicKey: Buffer): Buffer {
43
+ if (!publicKey) {
44
+ const engine = createEciesTranslationEngine();
45
+ const pluginEngine = getEciesPluginI18nEngine();
46
+ throw new ECIESError(
47
+ ECIESErrorTypeEnum.InvalidEphemeralPublicKey,
48
+ engine,
49
+ undefined,
50
+ undefined,
51
+ {
52
+ error: pluginEngine.translate(NodeEciesComponentId, NodeEciesStringKey.Error_InvalidPublicKey),
53
+ },
54
+ );
55
+ }
56
+
57
+ const keyLength = publicKey.length;
58
+
59
+ // Already in correct format (65 bytes with 0x04 prefix)
60
+ if (
61
+ keyLength === this._consts.PUBLIC_KEY_LENGTH &&
62
+ publicKey[0] === this._consts.PUBLIC_KEY_MAGIC
63
+ ) {
64
+ return publicKey;
65
+ }
66
+
67
+ // Raw key without prefix (64 bytes) - add the 0x04 prefix
68
+ if (keyLength === this._consts.RAW_PUBLIC_KEY_LENGTH) {
69
+ return Buffer.concat([Buffer.from([this._consts.PUBLIC_KEY_MAGIC]), publicKey]);
70
+ }
71
+
72
+ const engine = createEciesTranslationEngine();
73
+ const pluginEngine = getEciesPluginI18nEngine();
74
+ // Invalid format
75
+ throw new ECIESError(
76
+ ECIESErrorTypeEnum.InvalidEphemeralPublicKey,
77
+ engine,
78
+ undefined,
79
+ undefined,
80
+ {
81
+ error: pluginEngine.translate(NodeEciesComponentId, NodeEciesStringKey.Error_InvalidPublicKeyFormat),
82
+ keyLength: String(keyLength),
83
+ expectedLength64: String(this._consts.RAW_PUBLIC_KEY_LENGTH),
84
+ expectedLength65: String(this._consts.PUBLIC_KEY_LENGTH),
85
+ keyPrefix: keyLength > 0 ? String(publicKey[0]) : 'N/A',
86
+ expectedPrefix: String(this._consts.PUBLIC_KEY_MAGIC),
87
+ },
88
+ );
89
+ }
90
+
91
+ /**
92
+ * Generate a new mnemonic
93
+ * @returns {SecureString} The new mnemonic
94
+ */
95
+ public generateNewMnemonic(): SecureString {
96
+ return new SecureString(generateMnemonic(this._config.mnemonicStrength));
97
+ }
98
+
99
+ /**
100
+ * Generate a new wallet from a seed
101
+ * @param seed {Buffer} The seed to generate the wallet from
102
+ * @returns {Wallet} The new wallet
103
+ */
104
+ public walletFromSeed(seed: Buffer): Wallet {
105
+ const hdWallet = hdkey.EthereumHDKey.fromMasterSeed(seed);
106
+ return hdWallet
107
+ .derivePath(this._config.primaryKeyDerivationPath)
108
+ .getWallet();
109
+ }
110
+
111
+ /**
112
+ * Generate a new wallet and seed from a mnemonic
113
+ * @param mnemonic {SecureString} The mnemonic to generate the wallet and seed from
114
+ * @returns {IWalletSeed} The new wallet and seed
115
+ */
116
+ public walletAndSeedFromMnemonic(mnemonic: SecureString): IWalletSeed {
117
+ if (!mnemonic.value || !validateMnemonic(mnemonic.value)) {
118
+ throw new ECIESError(
119
+ ECIESErrorTypeEnum.InvalidMnemonic,
120
+ createEciesTranslationEngine(),
121
+ );
122
+ }
123
+
124
+ const seed = mnemonicToSeedSync(mnemonic.value);
125
+ const wallet = this.walletFromSeed(seed);
126
+
127
+ return {
128
+ seed: new SecureBuffer(seed),
129
+ wallet,
130
+ };
131
+ }
132
+
133
+ /**
134
+ * Generate a new wallet and seed from a mnemonic
135
+ * @param wallet {Wallet} The wallet to generate the key pair from
136
+ * @returns {ISimpleKeyPairBuffer} The new key pair
137
+ */
138
+ public walletToSimpleKeyPairBuffer(wallet: Wallet): ISimpleKeyPairBuffer {
139
+ const privateKey = Buffer.from(wallet.getPrivateKey());
140
+ const buf04 = new Uint8Array(1);
141
+ buf04[0] = this._consts.PUBLIC_KEY_MAGIC;
142
+ const publicKey = Buffer.concat([buf04, wallet.getPublicKey()]);
143
+
144
+ return {
145
+ privateKey,
146
+ publicKey,
147
+ };
148
+ }
149
+
150
+ /**
151
+ * Create a simple key pair from a seed
152
+ * @param seed {Buffer} The seed to generate the key pair from
153
+ * @returns {ISimpleKeyPairBuffer} The new key pair
154
+ */
155
+ public seedToSimpleKeyPairBuffer(seed: Buffer): ISimpleKeyPairBuffer {
156
+ const wallet = this.walletFromSeed(seed);
157
+ return this.walletToSimpleKeyPairBuffer(wallet);
158
+ }
159
+
160
+ /**
161
+ * Create a simple key pair from a mnemonic
162
+ * @param mnemonic {SecureString} The mnemonic to generate the key pair from
163
+ * @returns {ISimpleKeyPairBuffer} The new key pair
164
+ */
165
+ public mnemonicToSimpleKeyPairBuffer(
166
+ mnemonic: SecureString,
167
+ ): ISimpleKeyPairBuffer {
168
+ const { seed } = this.walletAndSeedFromMnemonic(mnemonic);
169
+ return this.seedToSimpleKeyPairBuffer(Buffer.from(seed.value));
170
+ }
171
+
172
+ /**
173
+ * Generate a random private key
174
+ * @returns {Buffer} The new private key
175
+ */
176
+ public generatePrivateKey(): Buffer {
177
+ return Buffer.from(secp256k1.utils.randomPrivateKey());
178
+ }
179
+
180
+ /**
181
+ * Get public key from private key
182
+ * @param privateKey {Buffer} The private key
183
+ * @returns {Buffer} The public key
184
+ */
185
+ public getPublicKey(privateKey: Buffer): Buffer {
186
+ const publicKey = secp256k1.getPublicKey(privateKey, false);
187
+ return Buffer.from(publicKey);
188
+ }
189
+
190
+ /**
191
+ * Generate ephemeral key pair for ECIES
192
+ * @returns {Promise<ISimpleKeyPairBuffer>} The key pair
193
+ */
194
+ public async generateEphemeralKeyPair(): Promise<{
195
+ privateKey: Buffer;
196
+ publicKey: Buffer;
197
+ }> {
198
+ const privateKey = this.generatePrivateKey();
199
+ const publicKey = this.getPublicKey(privateKey);
200
+ return { privateKey, publicKey };
201
+ }
202
+
203
+ /**
204
+ * Compute ECDH shared secret
205
+ * @param privateKey {Buffer} The private key
206
+ * @param publicKey {Buffer} The public key
207
+ * @returns {Buffer} The shared secret
208
+ */
209
+ public computeSharedSecret(privateKey: Buffer, publicKey: Buffer): Buffer {
210
+ const sharedSecret = secp256k1.getSharedSecret(privateKey, publicKey, true);
211
+ return Buffer.from(sharedSecret.slice(1)); // Remove the 0x02/0x03 prefix
212
+ }
213
+ }
@@ -0,0 +1,174 @@
1
+ import * as fs from 'fs';
2
+ import { ECIESService } from './service';
3
+
4
+ interface ChunkedFileHeader {
5
+ version: number;
6
+ chunkSize: number;
7
+ totalChunks: number;
8
+ originalSize: number;
9
+ }
10
+
11
+ export class EciesFileService {
12
+ protected readonly eciesService: ECIESService;
13
+ protected readonly userPrivateKey: Buffer;
14
+ protected readonly config: { chunkSize: number; headerSize: number };
15
+
16
+ constructor(
17
+ eciesService: ECIESService,
18
+ userPrivateKey: Buffer,
19
+ config: { chunkSize: number; headerSize: number } = {
20
+ chunkSize: 1024 * 1024, // 1MB chunks
21
+ headerSize: 20,
22
+ }
23
+ ) {
24
+ this.eciesService = eciesService;
25
+ this.userPrivateKey = userPrivateKey;
26
+ this.config = Object.freeze(config);
27
+ }
28
+
29
+ decryptFile(encryptedData: Buffer): Buffer {
30
+ const { header, chunks } = this.parseEncryptedFile(encryptedData);
31
+ const decryptedChunks: Buffer[] = [];
32
+
33
+ for (const chunk of chunks) {
34
+ const decrypted = this.eciesService.decryptSimpleOrSingleWithHeader(
35
+ false,
36
+ this.userPrivateKey,
37
+ chunk,
38
+ );
39
+ decryptedChunks.push(decrypted);
40
+ }
41
+
42
+ const result = Buffer.alloc(header.originalSize);
43
+ let offset = 0;
44
+ for (const chunk of decryptedChunks) {
45
+ const copyLength = Math.min(chunk.length, header.originalSize - offset);
46
+ chunk.copy(result, offset, 0, copyLength);
47
+ offset += copyLength;
48
+ }
49
+ return result;
50
+ }
51
+
52
+ encryptFileFromPath(filePath: string, recipientPublicKey: Buffer): Buffer {
53
+ const stats = fs.statSync(filePath);
54
+ const totalChunks = Math.ceil(stats.size / this.config.chunkSize);
55
+ const header: ChunkedFileHeader = {
56
+ version: 1,
57
+ chunkSize: this.config.chunkSize,
58
+ totalChunks,
59
+ originalSize: stats.size,
60
+ };
61
+
62
+ const headerBytes = this.serializeHeader(header);
63
+ const encryptedHeader = this.eciesService.encryptSimpleOrSingle(
64
+ false,
65
+ recipientPublicKey,
66
+ headerBytes,
67
+ );
68
+
69
+ const chunks: Buffer[] = [encryptedHeader];
70
+ const fd = fs.openSync(filePath, 'r');
71
+
72
+ try {
73
+ for (let i = 0; i < totalChunks; i++) {
74
+ const offset = i * this.config.chunkSize;
75
+ const chunkSize = Math.min(
76
+ this.config.chunkSize,
77
+ stats.size - offset,
78
+ );
79
+ const chunkData = Buffer.alloc(chunkSize);
80
+ fs.readSync(fd, chunkData, 0, chunkSize, offset);
81
+
82
+ const encryptedChunk = this.eciesService.encryptSimpleOrSingle(
83
+ false,
84
+ recipientPublicKey,
85
+ chunkData,
86
+ );
87
+ chunks.push(encryptedChunk);
88
+ }
89
+ } finally {
90
+ fs.closeSync(fd);
91
+ }
92
+
93
+ return Buffer.concat(chunks);
94
+ }
95
+
96
+ decryptFileToPath(encryptedData: Buffer, outputPath: string): void {
97
+ const { header, chunks } = this.parseEncryptedFile(encryptedData);
98
+ const fd = fs.openSync(outputPath, 'w');
99
+ let offset = 0;
100
+
101
+ try {
102
+ for (const chunk of chunks) {
103
+ const decrypted = this.eciesService.decryptSimpleOrSingleWithHeader(
104
+ false,
105
+ this.userPrivateKey,
106
+ chunk,
107
+ );
108
+ const writeLength = Math.min(
109
+ decrypted.length,
110
+ header.originalSize - offset,
111
+ );
112
+ fs.writeSync(fd, decrypted, 0, writeLength, offset);
113
+ offset += writeLength;
114
+ }
115
+ } finally {
116
+ fs.closeSync(fd);
117
+ }
118
+ }
119
+
120
+ protected serializeHeader(header: ChunkedFileHeader): Buffer {
121
+ const buffer = Buffer.alloc(this.config.headerSize);
122
+ buffer.writeUInt32BE(header.version, 0);
123
+ buffer.writeUInt32BE(header.chunkSize, 4);
124
+ buffer.writeUInt32BE(header.totalChunks, 8);
125
+ buffer.writeUInt32BE(header.originalSize, 12);
126
+ return buffer;
127
+ }
128
+
129
+ protected deserializeHeader(data: Buffer): ChunkedFileHeader {
130
+ return {
131
+ version: data.readUInt32BE(0),
132
+ chunkSize: data.readUInt32BE(4),
133
+ totalChunks: data.readUInt32BE(8),
134
+ originalSize: data.readUInt32BE(12),
135
+ };
136
+ }
137
+
138
+ protected parseEncryptedFile(encryptedData: Buffer): {
139
+ header: ChunkedFileHeader;
140
+ chunks: Buffer[];
141
+ } {
142
+ const headerLength = this.eciesService.computeEncryptedLengthFromDataLength(
143
+ this.config.headerSize,
144
+ 'single',
145
+ );
146
+
147
+ const encryptedHeader = encryptedData.subarray(0, headerLength);
148
+ const decryptedHeaderBytes =
149
+ this.eciesService.decryptSimpleOrSingleWithHeader(
150
+ false,
151
+ this.userPrivateKey,
152
+ encryptedHeader,
153
+ );
154
+
155
+ const header = this.deserializeHeader(decryptedHeaderBytes);
156
+ const chunks: Buffer[] = [];
157
+ let offset = headerLength;
158
+
159
+ for (let i = 0; i < header.totalChunks; i++) {
160
+ const chunkLength =
161
+ this.eciesService.computeEncryptedLengthFromDataLength(
162
+ i === header.totalChunks - 1
163
+ ? header.originalSize % header.chunkSize || header.chunkSize
164
+ : header.chunkSize,
165
+ 'single',
166
+ );
167
+
168
+ chunks.push(encryptedData.subarray(offset, offset + chunkLength));
169
+ offset += chunkLength;
170
+ }
171
+
172
+ return { header, chunks };
173
+ }
174
+ }
@@ -5,4 +5,3 @@ export * from './service';
5
5
  export * from './signature';
6
6
  export * from './single-recipient';
7
7
  export * from './utilities';
8
- //# sourceMappingURL=index.d.ts.map