@digitaldefiance/ecies-lib 1.1.23 → 1.1.24
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/README.md +4 -0
- package/package.json +13 -33
- package/src/constants.ts +474 -0
- package/src/email-string.ts +83 -0
- package/src/enumerations/ecies-encryption-type.ts +102 -0
- package/src/enumerations/ecies-error-type.ts +31 -0
- package/src/enumerations/ecies-string-key.ts +108 -0
- package/src/enumerations/guid-brand-type.ts +26 -0
- package/src/enumerations/guid-error-type.ts +6 -0
- package/{dist/enumerations/index.d.ts → src/enumerations/index.ts} +0 -1
- package/src/enumerations/invalid-email-type.ts +5 -0
- package/src/enumerations/length-encoding-type.ts +6 -0
- package/src/enumerations/length-error-type.ts +5 -0
- package/src/enumerations/member-error-type.ts +106 -0
- package/{dist/enumerations/member-type.d.ts → src/enumerations/member-type.ts} +7 -6
- package/src/enumerations/password-login-error-type.ts +4 -0
- package/src/enumerations/pbkdf2-error-type.ts +5 -0
- package/src/enumerations/pbkdf2-profile.ts +5 -0
- package/src/enumerations/secure-storage-error-type.ts +5 -0
- package/src/errors/disposed.ts +15 -0
- package/src/errors/ecies.ts +34 -0
- package/src/errors/guid.ts +34 -0
- package/{dist/errors/index.d.ts → src/errors/index.ts} +0 -1
- package/src/errors/invalid-email.ts +11 -0
- package/src/errors/length.ts +11 -0
- package/src/errors/member.ts +12 -0
- package/src/errors/pbkdf2.ts +12 -0
- package/src/errors/secure-storage.ts +13 -0
- package/src/errors/simple-ecies.ts +18 -0
- package/src/errors/simple-test-error.ts +6 -0
- package/src/guid.ts +800 -0
- package/src/i18n-setup.ts +1312 -0
- package/{dist/index.d.ts → src/index.ts} +0 -1
- package/src/interfaces/checksum-config.ts +4 -0
- package/src/interfaces/checksum-consts.ts +13 -0
- package/src/interfaces/constants.ts +48 -0
- package/src/interfaces/ecies-config.ts +8 -0
- package/src/interfaces/ecies-consts.ts +70 -0
- package/src/interfaces/ecies-file-service.ts +6 -0
- package/src/interfaces/guid.ts +53 -0
- package/{dist/interfaces/index.d.ts → src/interfaces/index.ts} +0 -1
- package/src/interfaces/library-error.ts +23 -0
- package/src/interfaces/member-operational.ts +54 -0
- package/{dist/interfaces/member-storage.d.ts → src/interfaces/member-storage.ts} +11 -10
- package/{dist/interfaces/member-with-mnemonic.d.ts → src/interfaces/member-with-mnemonic.ts} +3 -3
- package/src/interfaces/pbkdf2-config.ts +6 -0
- package/src/interfaces/pbkdf2-consts.ts +10 -0
- package/src/interfaces/pbkdf2-result.ts +5 -0
- package/src/member.ts +429 -0
- package/{dist/pbkdf2-profiles.d.ts → src/pbkdf2-profiles.ts} +2 -2
- package/src/phone-number.ts +18 -0
- package/src/regexes.ts +10 -0
- package/src/secure-buffer.ts +183 -0
- package/src/secure-string.ts +229 -0
- package/src/services/aes-gcm.ts +177 -0
- package/src/services/ecies/README.md +147 -0
- package/src/services/ecies/crypto-core.ts +180 -0
- package/src/services/ecies/example.ts +185 -0
- package/src/services/ecies/file.ts +167 -0
- package/{dist/services/ecies/index.d.ts → src/services/ecies/index.ts} +3 -1
- package/src/services/ecies/integration.ts +241 -0
- package/src/services/ecies/interfaces.ts +59 -0
- package/src/services/ecies/manual-test.ts +219 -0
- package/src/services/ecies/multi-recipient.ts +394 -0
- package/src/services/ecies/service.ts +317 -0
- package/src/services/ecies/signature.ts +93 -0
- package/src/services/ecies/single-recipient.ts +340 -0
- package/{dist/services/index.d.ts → src/services/index.ts} +0 -1
- package/src/services/password-login.ts +228 -0
- package/src/services/pbkdf2.ts +172 -0
- package/src/services/xor.ts +65 -0
- package/src/types/deep-partial.ts +11 -0
- package/{dist/types.d.ts → src/types.ts} +10 -4
- package/src/utils.ts +331 -0
- package/dist/constants.d.ts +0 -46
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js +0 -358
- package/dist/constants.js.map +0 -1
- package/dist/email-string.d.ts +0 -42
- package/dist/email-string.d.ts.map +0 -1
- package/dist/email-string.js +0 -75
- package/dist/email-string.js.map +0 -1
- package/dist/enumerations/ecies-encryption-type.d.ts +0 -15
- package/dist/enumerations/ecies-encryption-type.d.ts.map +0 -1
- package/dist/enumerations/ecies-encryption-type.js +0 -71
- package/dist/enumerations/ecies-encryption-type.js.map +0 -1
- package/dist/enumerations/ecies-error-type.d.ts +0 -32
- package/dist/enumerations/ecies-error-type.d.ts.map +0 -1
- package/dist/enumerations/ecies-error-type.js +0 -36
- package/dist/enumerations/ecies-error-type.js.map +0 -1
- package/dist/enumerations/ecies-string-key.d.ts +0 -96
- package/dist/enumerations/ecies-string-key.d.ts.map +0 -1
- package/dist/enumerations/ecies-string-key.js +0 -105
- package/dist/enumerations/ecies-string-key.js.map +0 -1
- package/dist/enumerations/guid-brand-type.d.ts +0 -27
- package/dist/enumerations/guid-brand-type.d.ts.map +0 -1
- package/dist/enumerations/guid-brand-type.js +0 -31
- package/dist/enumerations/guid-brand-type.js.map +0 -1
- package/dist/enumerations/guid-error-type.d.ts +0 -7
- package/dist/enumerations/guid-error-type.d.ts.map +0 -1
- package/dist/enumerations/guid-error-type.js +0 -11
- package/dist/enumerations/guid-error-type.js.map +0 -1
- package/dist/enumerations/index.d.ts.map +0 -1
- package/dist/enumerations/index.js +0 -31
- package/dist/enumerations/index.js.map +0 -1
- package/dist/enumerations/invalid-email-type.d.ts +0 -6
- package/dist/enumerations/invalid-email-type.d.ts.map +0 -1
- package/dist/enumerations/invalid-email-type.js +0 -10
- package/dist/enumerations/invalid-email-type.js.map +0 -1
- package/dist/enumerations/length-encoding-type.d.ts +0 -7
- package/dist/enumerations/length-encoding-type.d.ts.map +0 -1
- package/dist/enumerations/length-encoding-type.js +0 -11
- package/dist/enumerations/length-encoding-type.js.map +0 -1
- package/dist/enumerations/length-error-type.d.ts +0 -6
- package/dist/enumerations/length-error-type.d.ts.map +0 -1
- package/dist/enumerations/length-error-type.js +0 -10
- package/dist/enumerations/length-error-type.js.map +0 -1
- package/dist/enumerations/member-error-type.d.ts +0 -87
- package/dist/enumerations/member-error-type.d.ts.map +0 -1
- package/dist/enumerations/member-error-type.js +0 -91
- package/dist/enumerations/member-error-type.js.map +0 -1
- package/dist/enumerations/member-type.d.ts.map +0 -1
- package/dist/enumerations/member-type.js +0 -19
- package/dist/enumerations/member-type.js.map +0 -1
- package/dist/enumerations/password-login-error-type.d.ts +0 -5
- package/dist/enumerations/password-login-error-type.d.ts.map +0 -1
- package/dist/enumerations/password-login-error-type.js +0 -9
- package/dist/enumerations/password-login-error-type.js.map +0 -1
- package/dist/enumerations/pbkdf2-error-type.d.ts +0 -6
- package/dist/enumerations/pbkdf2-error-type.d.ts.map +0 -1
- package/dist/enumerations/pbkdf2-error-type.js +0 -10
- package/dist/enumerations/pbkdf2-error-type.js.map +0 -1
- package/dist/enumerations/pbkdf2-profile.d.ts +0 -6
- package/dist/enumerations/pbkdf2-profile.d.ts.map +0 -1
- package/dist/enumerations/pbkdf2-profile.js +0 -10
- package/dist/enumerations/pbkdf2-profile.js.map +0 -1
- package/dist/enumerations/secure-storage-error-type.d.ts +0 -6
- package/dist/enumerations/secure-storage-error-type.d.ts.map +0 -1
- package/dist/enumerations/secure-storage-error-type.js +0 -10
- package/dist/enumerations/secure-storage-error-type.js.map +0 -1
- package/dist/errors/disposed.d.ts +0 -4
- package/dist/errors/disposed.d.ts.map +0 -1
- package/dist/errors/disposed.js +0 -20
- package/dist/errors/disposed.js.map +0 -1
- package/dist/errors/ecies.d.ts +0 -7
- package/dist/errors/ecies.d.ts.map +0 -1
- package/dist/errors/ecies.js +0 -15
- package/dist/errors/ecies.js.map +0 -1
- package/dist/errors/guid.d.ts +0 -15
- package/dist/errors/guid.d.ts.map +0 -1
- package/dist/errors/guid.js +0 -26
- package/dist/errors/guid.js.map +0 -1
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js +0 -25
- package/dist/errors/index.js.map +0 -1
- package/dist/errors/invalid-email.d.ts +0 -7
- package/dist/errors/invalid-email.d.ts.map +0 -1
- package/dist/errors/invalid-email.js +0 -14
- package/dist/errors/invalid-email.js.map +0 -1
- package/dist/errors/length.d.ts +0 -7
- package/dist/errors/length.d.ts.map +0 -1
- package/dist/errors/length.js +0 -14
- package/dist/errors/length.js.map +0 -1
- package/dist/errors/member.d.ts +0 -7
- package/dist/errors/member.d.ts.map +0 -1
- package/dist/errors/member.js +0 -14
- package/dist/errors/member.js.map +0 -1
- package/dist/errors/pbkdf2.d.ts +0 -7
- package/dist/errors/pbkdf2.d.ts.map +0 -1
- package/dist/errors/pbkdf2.js +0 -14
- package/dist/errors/pbkdf2.js.map +0 -1
- package/dist/errors/secure-storage.d.ts +0 -7
- package/dist/errors/secure-storage.d.ts.map +0 -1
- package/dist/errors/secure-storage.js +0 -15
- package/dist/errors/secure-storage.js.map +0 -1
- package/dist/errors/simple-ecies.d.ts +0 -6
- package/dist/errors/simple-ecies.d.ts.map +0 -1
- package/dist/errors/simple-ecies.js +0 -15
- package/dist/errors/simple-ecies.js.map +0 -1
- package/dist/errors/simple-test-error.d.ts +0 -4
- package/dist/errors/simple-test-error.d.ts.map +0 -1
- package/dist/errors/simple-test-error.js +0 -11
- package/dist/errors/simple-test-error.js.map +0 -1
- package/dist/guid.d.ts +0 -153
- package/dist/guid.d.ts.map +0 -1
- package/dist/guid.js +0 -647
- package/dist/guid.js.map +0 -1
- package/dist/i18n-setup.d.ts +0 -24
- package/dist/i18n-setup.d.ts.map +0 -1
- package/dist/i18n-setup.js +0 -837
- package/dist/i18n-setup.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -32
- package/dist/index.js.map +0 -1
- package/dist/interfaces/checksum-config.d.ts +0 -5
- package/dist/interfaces/checksum-config.d.ts.map +0 -1
- package/dist/interfaces/checksum-config.js +0 -3
- package/dist/interfaces/checksum-config.js.map +0 -1
- package/dist/interfaces/checksum-consts.d.ts +0 -11
- package/dist/interfaces/checksum-consts.d.ts.map +0 -1
- package/dist/interfaces/checksum-consts.js +0 -3
- package/dist/interfaces/checksum-consts.js.map +0 -1
- package/dist/interfaces/constants.d.ts +0 -45
- package/dist/interfaces/constants.d.ts.map +0 -1
- package/dist/interfaces/constants.js +0 -3
- package/dist/interfaces/constants.js.map +0 -1
- package/dist/interfaces/ecies-config.d.ts +0 -9
- package/dist/interfaces/ecies-config.d.ts.map +0 -1
- package/dist/interfaces/ecies-config.js +0 -3
- package/dist/interfaces/ecies-config.js.map +0 -1
- package/dist/interfaces/ecies-consts.d.ts +0 -58
- package/dist/interfaces/ecies-consts.d.ts.map +0 -1
- package/dist/interfaces/ecies-consts.js +0 -3
- package/dist/interfaces/ecies-consts.js.map +0 -1
- package/dist/interfaces/ecies-file-service.d.ts +0 -7
- package/dist/interfaces/ecies-file-service.d.ts.map +0 -1
- package/dist/interfaces/ecies-file-service.js +0 -3
- package/dist/interfaces/ecies-file-service.js.map +0 -1
- package/dist/interfaces/guid.d.ts +0 -45
- package/dist/interfaces/guid.d.ts.map +0 -1
- package/dist/interfaces/guid.js +0 -3
- package/dist/interfaces/guid.js.map +0 -1
- package/dist/interfaces/index.d.ts.map +0 -1
- package/dist/interfaces/index.js +0 -30
- package/dist/interfaces/index.js.map +0 -1
- package/dist/interfaces/library-error.d.ts +0 -23
- package/dist/interfaces/library-error.d.ts.map +0 -1
- package/dist/interfaces/library-error.js +0 -3
- package/dist/interfaces/library-error.js.map +0 -1
- package/dist/interfaces/member-operational.d.ts +0 -40
- package/dist/interfaces/member-operational.d.ts.map +0 -1
- package/dist/interfaces/member-operational.js +0 -3
- package/dist/interfaces/member-operational.js.map +0 -1
- package/dist/interfaces/member-storage.d.ts.map +0 -1
- package/dist/interfaces/member-storage.js +0 -3
- package/dist/interfaces/member-storage.js.map +0 -1
- package/dist/interfaces/member-with-mnemonic.d.ts.map +0 -1
- package/dist/interfaces/member-with-mnemonic.js +0 -3
- package/dist/interfaces/member-with-mnemonic.js.map +0 -1
- package/dist/interfaces/pbkdf2-config.d.ts +0 -7
- package/dist/interfaces/pbkdf2-config.d.ts.map +0 -1
- package/dist/interfaces/pbkdf2-config.js +0 -3
- package/dist/interfaces/pbkdf2-config.js.map +0 -1
- package/dist/interfaces/pbkdf2-consts.d.ts +0 -9
- package/dist/interfaces/pbkdf2-consts.d.ts.map +0 -1
- package/dist/interfaces/pbkdf2-consts.js +0 -3
- package/dist/interfaces/pbkdf2-consts.js.map +0 -1
- package/dist/interfaces/pbkdf2-result.d.ts +0 -6
- package/dist/interfaces/pbkdf2-result.d.ts.map +0 -1
- package/dist/interfaces/pbkdf2-result.js +0 -3
- package/dist/interfaces/pbkdf2-result.js.map +0 -1
- package/dist/member.d.ts +0 -66
- package/dist/member.d.ts.map +0 -1
- package/dist/member.js +0 -271
- package/dist/member.js.map +0 -1
- package/dist/pbkdf2-profiles.d.ts.map +0 -1
- package/dist/pbkdf2-profiles.js +0 -3
- package/dist/pbkdf2-profiles.js.map +0 -1
- package/dist/phone-number.d.ts +0 -6
- package/dist/phone-number.d.ts.map +0 -1
- package/dist/phone-number.js +0 -22
- package/dist/phone-number.js.map +0 -1
- package/dist/regexes.d.ts +0 -7
- package/dist/regexes.d.ts.map +0 -1
- package/dist/regexes.js +0 -10
- package/dist/regexes.js.map +0 -1
- package/dist/secure-buffer.d.ts +0 -38
- package/dist/secure-buffer.d.ts.map +0 -1
- package/dist/secure-buffer.js +0 -168
- package/dist/secure-buffer.js.map +0 -1
- package/dist/secure-string.d.ts +0 -39
- package/dist/secure-string.d.ts.map +0 -1
- package/dist/secure-string.js +0 -195
- package/dist/secure-string.js.map +0 -1
- package/dist/services/aes-gcm.d.ts +0 -57
- package/dist/services/aes-gcm.d.ts.map +0 -1
- package/dist/services/aes-gcm.js +0 -111
- package/dist/services/aes-gcm.js.map +0 -1
- package/dist/services/ecies/crypto-core.d.ts +0 -51
- package/dist/services/ecies/crypto-core.d.ts.map +0 -1
- package/dist/services/ecies/crypto-core.js +0 -139
- package/dist/services/ecies/crypto-core.js.map +0 -1
- package/dist/services/ecies/example.d.ts +0 -25
- package/dist/services/ecies/example.d.ts.map +0 -1
- package/dist/services/ecies/example.js +0 -128
- package/dist/services/ecies/example.js.map +0 -1
- package/dist/services/ecies/file.d.ts +0 -18
- package/dist/services/ecies/file.d.ts.map +0 -1
- package/dist/services/ecies/file.js +0 -110
- package/dist/services/ecies/file.js.map +0 -1
- package/dist/services/ecies/index.d.ts.map +0 -1
- package/dist/services/ecies/index.js +0 -57
- package/dist/services/ecies/index.js.map +0 -1
- package/dist/services/ecies/integration.d.ts +0 -59
- package/dist/services/ecies/integration.d.ts.map +0 -1
- package/dist/services/ecies/integration.js +0 -172
- package/dist/services/ecies/integration.js.map +0 -1
- package/dist/services/ecies/interfaces.d.ts +0 -51
- package/dist/services/ecies/interfaces.d.ts.map +0 -1
- package/dist/services/ecies/interfaces.js +0 -6
- package/dist/services/ecies/interfaces.js.map +0 -1
- package/dist/services/ecies/manual-test.d.ts +0 -29
- package/dist/services/ecies/manual-test.d.ts.map +0 -1
- package/dist/services/ecies/manual-test.js +0 -171
- package/dist/services/ecies/manual-test.js.map +0 -1
- package/dist/services/ecies/multi-recipient.d.ts +0 -52
- package/dist/services/ecies/multi-recipient.d.ts.map +0 -1
- package/dist/services/ecies/multi-recipient.js +0 -243
- package/dist/services/ecies/multi-recipient.js.map +0 -1
- package/dist/services/ecies/service.d.ts +0 -104
- package/dist/services/ecies/service.d.ts.map +0 -1
- package/dist/services/ecies/service.js +0 -192
- package/dist/services/ecies/service.js.map +0 -1
- package/dist/services/ecies/signature.d.ts +0 -27
- package/dist/services/ecies/signature.d.ts.map +0 -1
- package/dist/services/ecies/signature.js +0 -76
- package/dist/services/ecies/signature.js.map +0 -1
- package/dist/services/ecies/single-recipient.d.ts +0 -46
- package/dist/services/ecies/single-recipient.d.ts.map +0 -1
- package/dist/services/ecies/single-recipient.js +0 -212
- package/dist/services/ecies/single-recipient.js.map +0 -1
- package/dist/services/index.d.ts.map +0 -1
- package/dist/services/index.js +0 -22
- package/dist/services/index.js.map +0 -1
- package/dist/services/password-login.d.ts +0 -49
- package/dist/services/password-login.d.ts.map +0 -1
- package/dist/services/password-login.js +0 -121
- package/dist/services/password-login.js.map +0 -1
- package/dist/services/pbkdf2.d.ts +0 -56
- package/dist/services/pbkdf2.d.ts.map +0 -1
- package/dist/services/pbkdf2.js +0 -114
- package/dist/services/pbkdf2.js.map +0 -1
- package/dist/services/xor.d.ts +0 -37
- package/dist/services/xor.d.ts.map +0 -1
- package/dist/services/xor.js +0 -67
- package/dist/services/xor.js.map +0 -1
- package/dist/types/deep-partial.d.ts +0 -4
- package/dist/types/deep-partial.d.ts.map +0 -1
- package/dist/types/deep-partial.js +0 -3
- package/dist/types/deep-partial.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/utils.d.ts +0 -68
- package/dist/utils.d.ts.map +0 -1
- package/dist/utils.js +0 -288
- package/dist/utils.js.map +0 -1
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { IECIESConstants } from '../../interfaces/ecies-consts';
|
|
2
|
+
import { Constants } from '../../constants';
|
|
3
|
+
import { IECIESConfig } from '../../interfaces/ecies-config';
|
|
4
|
+
import { concatUint8Arrays } from '../../utils';
|
|
5
|
+
import { AESGCMService } from '../aes-gcm';
|
|
6
|
+
import { EciesCryptoCore } from './crypto-core';
|
|
7
|
+
import {
|
|
8
|
+
IMultiEncryptedMessage,
|
|
9
|
+
IMultiEncryptedParsedHeader,
|
|
10
|
+
IMultiRecipient,
|
|
11
|
+
} from './interfaces';
|
|
12
|
+
import { EciesComponentId, getEciesI18nEngine } from '../../i18n-setup';
|
|
13
|
+
import { EciesStringKey } from '../../enumerations';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Browser-compatible multi-recipient ECIES encryption/decryption
|
|
17
|
+
*/
|
|
18
|
+
export class EciesMultiRecipient {
|
|
19
|
+
protected readonly cryptoCore: EciesCryptoCore;
|
|
20
|
+
protected readonly eciesConsts: IECIESConstants;
|
|
21
|
+
|
|
22
|
+
constructor(config: IECIESConfig, eciesParams: IECIESConstants = Constants.ECIES) {
|
|
23
|
+
this.cryptoCore = new EciesCryptoCore(config, eciesParams);
|
|
24
|
+
this.eciesConsts = eciesParams;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Get the header size for multi-recipient encryption
|
|
29
|
+
*/
|
|
30
|
+
public getHeaderSize(recipientCount: number): number {
|
|
31
|
+
return (
|
|
32
|
+
this.eciesConsts.MULTIPLE.DATA_LENGTH_SIZE +
|
|
33
|
+
this.eciesConsts.MULTIPLE.RECIPIENT_COUNT_SIZE +
|
|
34
|
+
recipientCount * this.eciesConsts.MULTIPLE.RECIPIENT_ID_SIZE +
|
|
35
|
+
recipientCount * this.eciesConsts.MULTIPLE.ENCRYPTED_KEY_SIZE
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Encrypt a message symmetric key with a public key
|
|
41
|
+
* @param receiverPublicKey The public key of the receiver
|
|
42
|
+
* @param messageSymmetricKey The message to encrypt
|
|
43
|
+
* @returns The encrypted message
|
|
44
|
+
*/
|
|
45
|
+
public async encryptKey(
|
|
46
|
+
receiverPublicKey: Uint8Array,
|
|
47
|
+
messageSymmetricKey: Uint8Array,
|
|
48
|
+
): Promise<Uint8Array> {
|
|
49
|
+
const ephemeralKeyPair = await this.cryptoCore.generateEphemeralKeyPair();
|
|
50
|
+
const sharedSecret = await this.cryptoCore.computeSharedSecret(
|
|
51
|
+
ephemeralKeyPair.privateKey,
|
|
52
|
+
receiverPublicKey,
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
const symKey = sharedSecret.slice(0, this.eciesConsts.SYMMETRIC.KEY_SIZE);
|
|
56
|
+
|
|
57
|
+
const encryptResult = await AESGCMService.encrypt(
|
|
58
|
+
messageSymmetricKey,
|
|
59
|
+
symKey,
|
|
60
|
+
true,
|
|
61
|
+
this.eciesConsts
|
|
62
|
+
);
|
|
63
|
+
const { encrypted, iv } = encryptResult;
|
|
64
|
+
const authTag = encryptResult.tag;
|
|
65
|
+
|
|
66
|
+
if (!authTag) {
|
|
67
|
+
const engine = getEciesI18nEngine();
|
|
68
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_AuthenticationTagIsRequiredForKeyEncryption));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return concatUint8Arrays(
|
|
72
|
+
new Uint8Array(ephemeralKeyPair.publicKey),
|
|
73
|
+
iv,
|
|
74
|
+
authTag,
|
|
75
|
+
encrypted,
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Decrypts symmetric key encrypted with ECIES
|
|
81
|
+
* @param privateKey The private key to decrypt the data
|
|
82
|
+
* @param encryptedKey The data to decrypt
|
|
83
|
+
* @returns The decrypted data buffer
|
|
84
|
+
*/
|
|
85
|
+
public async decryptKey(
|
|
86
|
+
privateKey: Uint8Array,
|
|
87
|
+
encryptedKey: Uint8Array,
|
|
88
|
+
): Promise<Uint8Array> {
|
|
89
|
+
if (encryptedKey.length !== this.eciesConsts.MULTIPLE.ENCRYPTED_KEY_SIZE) {
|
|
90
|
+
const engine = getEciesI18nEngine();
|
|
91
|
+
throw new Error(engine.translate(
|
|
92
|
+
EciesComponentId,
|
|
93
|
+
EciesStringKey.Error_ECIESError_InvalidEncryptedKeyLengthTemplate, {keySize: this.eciesConsts.MULTIPLE.ENCRYPTED_KEY_SIZE, encryptedKeyLength: encryptedKey.length}));
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
const ephemeralPublicKey = encryptedKey.slice(0, this.eciesConsts.PUBLIC_KEY_LENGTH);
|
|
97
|
+
const iv = encryptedKey.slice(
|
|
98
|
+
this.eciesConsts.PUBLIC_KEY_LENGTH,
|
|
99
|
+
this.eciesConsts.PUBLIC_KEY_LENGTH + this.eciesConsts.IV_SIZE,
|
|
100
|
+
);
|
|
101
|
+
const authTag = encryptedKey.slice(
|
|
102
|
+
this.eciesConsts.PUBLIC_KEY_LENGTH + this.eciesConsts.IV_SIZE,
|
|
103
|
+
this.eciesConsts.PUBLIC_KEY_LENGTH + this.eciesConsts.IV_SIZE + this.eciesConsts.AUTH_TAG_SIZE,
|
|
104
|
+
);
|
|
105
|
+
const encrypted = encryptedKey.slice(
|
|
106
|
+
this.eciesConsts.PUBLIC_KEY_LENGTH + this.eciesConsts.IV_SIZE + this.eciesConsts.AUTH_TAG_SIZE,
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const sharedSecret = await this.cryptoCore.computeSharedSecret(
|
|
110
|
+
privateKey,
|
|
111
|
+
ephemeralPublicKey,
|
|
112
|
+
);
|
|
113
|
+
const symKey = sharedSecret.slice(0, this.eciesConsts.SYMMETRIC.KEY_SIZE);
|
|
114
|
+
|
|
115
|
+
const encryptedWithTag = AESGCMService.combineEncryptedDataAndTag(
|
|
116
|
+
encrypted,
|
|
117
|
+
authTag,
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
try {
|
|
121
|
+
const decrypted = await AESGCMService.decrypt(
|
|
122
|
+
iv,
|
|
123
|
+
encryptedWithTag,
|
|
124
|
+
symKey,
|
|
125
|
+
true,
|
|
126
|
+
this.eciesConsts
|
|
127
|
+
);
|
|
128
|
+
if (decrypted.length !== this.eciesConsts.SYMMETRIC.KEY_SIZE) {
|
|
129
|
+
const engine = getEciesI18nEngine();
|
|
130
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_InvalidDataLength));
|
|
131
|
+
}
|
|
132
|
+
return decrypted;
|
|
133
|
+
} catch (error) {
|
|
134
|
+
console.error('Failed to decrypt key:', error);
|
|
135
|
+
const engine = getEciesI18nEngine();
|
|
136
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_FailedToDecryptKey));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Encrypt a message for multiple recipients
|
|
142
|
+
*/
|
|
143
|
+
public async encryptMultiple(
|
|
144
|
+
recipients: IMultiRecipient[],
|
|
145
|
+
message: Uint8Array,
|
|
146
|
+
preamble: Uint8Array = new Uint8Array(0),
|
|
147
|
+
): Promise<IMultiEncryptedMessage> {
|
|
148
|
+
const engine = getEciesI18nEngine();
|
|
149
|
+
if (recipients.length > this.eciesConsts.MULTIPLE.MAX_RECIPIENTS) {
|
|
150
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_TooManyRecipientsTemplate, { recipientsCount: recipients.length }));
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (message.length > this.eciesConsts.MAX_RAW_DATA_SIZE) {
|
|
154
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_MessageTooLargeTemplate, { length: message.length }));
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Generate symmetric key
|
|
158
|
+
const symmetricKey = crypto.getRandomValues(
|
|
159
|
+
new Uint8Array(this.eciesConsts.SYMMETRIC.KEY_SIZE),
|
|
160
|
+
);
|
|
161
|
+
|
|
162
|
+
// Encrypt message with symmetric key
|
|
163
|
+
const encryptResult = await AESGCMService.encrypt(
|
|
164
|
+
message,
|
|
165
|
+
symmetricKey,
|
|
166
|
+
true,
|
|
167
|
+
this.eciesConsts
|
|
168
|
+
);
|
|
169
|
+
const { encrypted, iv } = encryptResult;
|
|
170
|
+
const authTag = encryptResult.tag;
|
|
171
|
+
|
|
172
|
+
if (!authTag) {
|
|
173
|
+
const engine = getEciesI18nEngine();
|
|
174
|
+
throw new Error(
|
|
175
|
+
engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_AuthenticationTagIsRequiredForMultiRecipientECIESEncryption),
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Create stored message: preamble + iv + authTag + encrypted
|
|
180
|
+
const storedMessage = concatUint8Arrays(preamble, iv, authTag, encrypted);
|
|
181
|
+
|
|
182
|
+
// Encrypt symmetric key for each recipient
|
|
183
|
+
const recipientIds: Uint8Array[] = [];
|
|
184
|
+
const recipientKeys: Uint8Array[] = [];
|
|
185
|
+
|
|
186
|
+
for (const recipient of recipients) {
|
|
187
|
+
const encryptedKey = await this.encryptKey(
|
|
188
|
+
recipient.publicKey,
|
|
189
|
+
symmetricKey,
|
|
190
|
+
);
|
|
191
|
+
|
|
192
|
+
recipientIds.push(recipient.id);
|
|
193
|
+
recipientKeys.push(encryptedKey);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
const headerSize = this.getHeaderSize(recipients.length);
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
dataLength: message.length,
|
|
200
|
+
recipientCount: recipients.length,
|
|
201
|
+
recipientIds,
|
|
202
|
+
recipientKeys,
|
|
203
|
+
encryptedMessage: storedMessage,
|
|
204
|
+
headerSize,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Decrypt a multi-recipient message for a specific recipient
|
|
210
|
+
*/
|
|
211
|
+
public async decryptMultipleForRecipient(
|
|
212
|
+
encryptedData: IMultiEncryptedMessage,
|
|
213
|
+
recipientId: Uint8Array,
|
|
214
|
+
privateKey: Uint8Array,
|
|
215
|
+
): Promise<Uint8Array> {
|
|
216
|
+
// Find recipient's encrypted key
|
|
217
|
+
const recipientIndex = encryptedData.recipientIds.findIndex((id) =>
|
|
218
|
+
this.arraysEqual(id, recipientId),
|
|
219
|
+
);
|
|
220
|
+
|
|
221
|
+
if (recipientIndex === -1) {
|
|
222
|
+
const engine = getEciesI18nEngine();
|
|
223
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_RecipientNotFound));
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const encryptedKey = encryptedData.recipientKeys[recipientIndex];
|
|
227
|
+
|
|
228
|
+
// Decrypt the symmetric key
|
|
229
|
+
const symmetricKey = await this.decryptKey(privateKey, encryptedKey);
|
|
230
|
+
|
|
231
|
+
// Extract components from encrypted message
|
|
232
|
+
let offset = 0;
|
|
233
|
+
const iv = encryptedData.encryptedMessage.slice(
|
|
234
|
+
offset,
|
|
235
|
+
offset + this.eciesConsts.IV_SIZE,
|
|
236
|
+
);
|
|
237
|
+
offset += this.eciesConsts.IV_SIZE;
|
|
238
|
+
|
|
239
|
+
const authTag = encryptedData.encryptedMessage.slice(
|
|
240
|
+
offset,
|
|
241
|
+
offset + this.eciesConsts.AUTH_TAG_SIZE,
|
|
242
|
+
);
|
|
243
|
+
offset += this.eciesConsts.AUTH_TAG_SIZE;
|
|
244
|
+
|
|
245
|
+
const encrypted = encryptedData.encryptedMessage.slice(offset);
|
|
246
|
+
|
|
247
|
+
// AES-GCM provides authentication via auth tag (no separate CRC needed)
|
|
248
|
+
|
|
249
|
+
// Decrypt with symmetric key
|
|
250
|
+
const encryptedWithTag = AESGCMService.combineEncryptedDataAndTag(
|
|
251
|
+
encrypted,
|
|
252
|
+
authTag,
|
|
253
|
+
);
|
|
254
|
+
|
|
255
|
+
const decrypted = await AESGCMService.decrypt(
|
|
256
|
+
iv,
|
|
257
|
+
encryptedWithTag,
|
|
258
|
+
symmetricKey,
|
|
259
|
+
true,
|
|
260
|
+
this.eciesConsts
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
// Verify length
|
|
264
|
+
if (decrypted.length !== encryptedData.dataLength) {
|
|
265
|
+
const engine = getEciesI18nEngine();
|
|
266
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_DecryptedDataLengthMismatch));
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
return decrypted;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Build header for multi-recipient message
|
|
274
|
+
*/
|
|
275
|
+
public buildHeader(data: IMultiEncryptedMessage): Uint8Array {
|
|
276
|
+
if (data.recipientIds.length !== data.recipientKeys.length) {
|
|
277
|
+
const engine = getEciesI18nEngine();
|
|
278
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_RecipientCountMismatch));
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (data.dataLength < 0 || data.dataLength > this.eciesConsts.MAX_RAW_DATA_SIZE) {
|
|
282
|
+
const engine = getEciesI18nEngine();
|
|
283
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_InvalidDataLength));
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Data length (8 bytes)
|
|
287
|
+
const dataLengthUint8Array = new Uint8Array(8);
|
|
288
|
+
new DataView(dataLengthUint8Array.buffer).setBigUint64(
|
|
289
|
+
0,
|
|
290
|
+
BigInt(data.dataLength),
|
|
291
|
+
false,
|
|
292
|
+
);
|
|
293
|
+
|
|
294
|
+
// Recipient count (2 bytes)
|
|
295
|
+
const recipientCountUint8Array = new Uint8Array(2);
|
|
296
|
+
new DataView(recipientCountUint8Array.buffer).setUint16(
|
|
297
|
+
0,
|
|
298
|
+
data.recipientIds.length,
|
|
299
|
+
false,
|
|
300
|
+
);
|
|
301
|
+
|
|
302
|
+
// Recipient IDs
|
|
303
|
+
const recipientIdsUint8Array = concatUint8Arrays(...data.recipientIds);
|
|
304
|
+
|
|
305
|
+
// Encrypted keys
|
|
306
|
+
const encryptedKeysUint8Array = concatUint8Arrays(...data.recipientKeys);
|
|
307
|
+
|
|
308
|
+
return concatUint8Arrays(
|
|
309
|
+
dataLengthUint8Array,
|
|
310
|
+
recipientCountUint8Array,
|
|
311
|
+
recipientIdsUint8Array,
|
|
312
|
+
encryptedKeysUint8Array,
|
|
313
|
+
);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Parse multi-recipient header
|
|
318
|
+
*/
|
|
319
|
+
public parseHeader(data: Uint8Array): IMultiEncryptedParsedHeader {
|
|
320
|
+
if (data.length < 10) {
|
|
321
|
+
const engine = getEciesI18nEngine();
|
|
322
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_DataTooShortForMultiRecipientHeader));
|
|
323
|
+
// minimum: 8 + 2
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
let offset = 0;
|
|
327
|
+
const view = new DataView(data.buffer, data.byteOffset);
|
|
328
|
+
|
|
329
|
+
// Read data length
|
|
330
|
+
const dataLength = Number(view.getBigUint64(offset, false));
|
|
331
|
+
offset += 8;
|
|
332
|
+
|
|
333
|
+
if (dataLength <= 0 || dataLength > this.eciesConsts.MAX_RAW_DATA_SIZE) {
|
|
334
|
+
const engine = getEciesI18nEngine();
|
|
335
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_InvalidDataLength));
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Read recipient count
|
|
339
|
+
const recipientCount = view.getUint16(offset, false);
|
|
340
|
+
offset += 2;
|
|
341
|
+
|
|
342
|
+
if (recipientCount <= 0 || recipientCount > this.eciesConsts.MULTIPLE.MAX_RECIPIENTS) {
|
|
343
|
+
const engine = getEciesI18nEngine();
|
|
344
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_ECIESError_InvalidRecipientCount));
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
// Read recipient IDs
|
|
348
|
+
const recipientIds: Uint8Array[] = [];
|
|
349
|
+
for (let i = 0; i < recipientCount; i++) {
|
|
350
|
+
recipientIds.push(
|
|
351
|
+
data.slice(offset, offset + this.eciesConsts.MULTIPLE.RECIPIENT_ID_SIZE),
|
|
352
|
+
);
|
|
353
|
+
offset += this.eciesConsts.MULTIPLE.RECIPIENT_ID_SIZE;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Read encrypted keys
|
|
357
|
+
const recipientKeys: Uint8Array[] = [];
|
|
358
|
+
for (let i = 0; i < recipientCount; i++) {
|
|
359
|
+
recipientKeys.push(
|
|
360
|
+
data.slice(offset, offset + this.eciesConsts.MULTIPLE.ENCRYPTED_KEY_SIZE),
|
|
361
|
+
);
|
|
362
|
+
offset += this.eciesConsts.MULTIPLE.ENCRYPTED_KEY_SIZE;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
dataLength,
|
|
367
|
+
recipientCount,
|
|
368
|
+
recipientIds,
|
|
369
|
+
recipientKeys,
|
|
370
|
+
headerSize: offset,
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Parse complete multi-recipient message
|
|
376
|
+
*/
|
|
377
|
+
public parseMessage(data: Uint8Array): IMultiEncryptedMessage {
|
|
378
|
+
const header = this.parseHeader(data);
|
|
379
|
+
const encryptedMessage = data.slice(header.headerSize);
|
|
380
|
+
|
|
381
|
+
return {
|
|
382
|
+
...header,
|
|
383
|
+
encryptedMessage,
|
|
384
|
+
};
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
private arraysEqual(a: Uint8Array, b: Uint8Array): boolean {
|
|
388
|
+
if (a.length !== b.length) return false;
|
|
389
|
+
for (let i = 0; i < a.length; i++) {
|
|
390
|
+
if (a[i] !== b[i]) return false;
|
|
391
|
+
}
|
|
392
|
+
return true;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { IECIESConstants } from '../../interfaces/ecies-consts';
|
|
2
|
+
import { Constants } from '../../constants';
|
|
3
|
+
import {
|
|
4
|
+
EciesEncryptionType,
|
|
5
|
+
EciesEncryptionTypeEnum,
|
|
6
|
+
} from '../../enumerations/ecies-encryption-type';
|
|
7
|
+
import { IECIESConfig } from '../../interfaces/ecies-config';
|
|
8
|
+
import { SecureString } from '../../secure-string';
|
|
9
|
+
import { SignatureString, SignatureUint8Array } from '../../types';
|
|
10
|
+
import { EciesCryptoCore } from './crypto-core';
|
|
11
|
+
import { ISimpleKeyPair, IWalletSeed } from './interfaces';
|
|
12
|
+
import { EciesSignature } from './signature';
|
|
13
|
+
import { EciesSingleRecipient } from './single-recipient';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Browser-compatible ECIES service that mirrors the server-side functionality
|
|
17
|
+
* Uses Web Crypto API and @scure/@noble libraries for browser compatibility
|
|
18
|
+
*/
|
|
19
|
+
export class ECIESService {
|
|
20
|
+
protected readonly _config: IECIESConfig;
|
|
21
|
+
protected readonly cryptoCore: EciesCryptoCore;
|
|
22
|
+
protected readonly signature: EciesSignature;
|
|
23
|
+
protected readonly singleRecipient: EciesSingleRecipient;
|
|
24
|
+
protected readonly eciesConsts: IECIESConstants;
|
|
25
|
+
|
|
26
|
+
constructor(config?: Partial<IECIESConfig>, eciesParams: IECIESConstants = Constants.ECIES) {
|
|
27
|
+
this.eciesConsts = eciesParams;
|
|
28
|
+
this._config = {
|
|
29
|
+
curveName: this.eciesConsts.CURVE_NAME,
|
|
30
|
+
primaryKeyDerivationPath: this.eciesConsts.PRIMARY_KEY_DERIVATION_PATH,
|
|
31
|
+
mnemonicStrength: this.eciesConsts.MNEMONIC_STRENGTH,
|
|
32
|
+
symmetricAlgorithm: this.eciesConsts.SYMMETRIC.ALGORITHM,
|
|
33
|
+
symmetricKeyBits: this.eciesConsts.SYMMETRIC.KEY_BITS,
|
|
34
|
+
symmetricKeyMode: this.eciesConsts.SYMMETRIC.MODE,
|
|
35
|
+
...config,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Initialize components
|
|
39
|
+
this.cryptoCore = new EciesCryptoCore(this._config, this.eciesConsts);
|
|
40
|
+
this.signature = new EciesSignature(this.cryptoCore);
|
|
41
|
+
this.singleRecipient = new EciesSingleRecipient(this._config);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
public get core(): EciesCryptoCore {
|
|
45
|
+
return this.cryptoCore;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
public get config(): IECIESConfig {
|
|
49
|
+
return this._config;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
public get curveName(): string {
|
|
53
|
+
return this._config.curveName;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// === Key Management Methods ===
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generate a new mnemonic
|
|
60
|
+
*/
|
|
61
|
+
public generateNewMnemonic(): SecureString {
|
|
62
|
+
return this.cryptoCore.generateNewMnemonic();
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Generate wallet and seed from mnemonic
|
|
67
|
+
*/
|
|
68
|
+
public walletAndSeedFromMnemonic(mnemonic: SecureString): IWalletSeed {
|
|
69
|
+
return this.cryptoCore.walletAndSeedFromMnemonic(mnemonic);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Create simple key pair from seed
|
|
74
|
+
*/
|
|
75
|
+
public seedToSimpleKeyPair(seed: Uint8Array): ISimpleKeyPair {
|
|
76
|
+
return this.cryptoCore.seedToSimpleKeyPair(seed);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Create simple key pair from mnemonic
|
|
81
|
+
*/
|
|
82
|
+
public mnemonicToSimpleKeyPair(mnemonic: SecureString): ISimpleKeyPair {
|
|
83
|
+
return this.cryptoCore.mnemonicToSimpleKeyPair(mnemonic);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get public key from private key
|
|
88
|
+
*/
|
|
89
|
+
public getPublicKey(privateKey: Uint8Array): Uint8Array {
|
|
90
|
+
return this.cryptoCore.getPublicKey(privateKey);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// === Core Encryption/Decryption Methods ===
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Encrypt for single recipient (simple or single mode)
|
|
97
|
+
*/
|
|
98
|
+
public async encryptSimpleOrSingle(
|
|
99
|
+
encryptSimple: boolean,
|
|
100
|
+
receiverPublicKey: Uint8Array,
|
|
101
|
+
message: Uint8Array,
|
|
102
|
+
preamble: Uint8Array = new Uint8Array(0),
|
|
103
|
+
): Promise<Uint8Array> {
|
|
104
|
+
return this.singleRecipient.encrypt(
|
|
105
|
+
encryptSimple,
|
|
106
|
+
receiverPublicKey,
|
|
107
|
+
message,
|
|
108
|
+
preamble,
|
|
109
|
+
);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Parse single encrypted header
|
|
114
|
+
*/
|
|
115
|
+
public parseSingleEncryptedHeader(
|
|
116
|
+
encryptionType: EciesEncryptionTypeEnum,
|
|
117
|
+
data: Uint8Array,
|
|
118
|
+
preambleSize: number = 0,
|
|
119
|
+
options?: { dataLength?: number },
|
|
120
|
+
) {
|
|
121
|
+
const { header } = this.singleRecipient.parseEncryptedMessage(
|
|
122
|
+
encryptionType,
|
|
123
|
+
data,
|
|
124
|
+
preambleSize,
|
|
125
|
+
options,
|
|
126
|
+
);
|
|
127
|
+
return header;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* Decrypt with header
|
|
132
|
+
*/
|
|
133
|
+
public async decryptSimpleOrSingleWithHeader(
|
|
134
|
+
decryptSimple: boolean,
|
|
135
|
+
privateKey: Uint8Array,
|
|
136
|
+
encryptedData: Uint8Array,
|
|
137
|
+
preambleSize: number = 0,
|
|
138
|
+
options?: { dataLength?: number },
|
|
139
|
+
): Promise<Uint8Array> {
|
|
140
|
+
return await this.singleRecipient.decryptWithHeader(
|
|
141
|
+
decryptSimple
|
|
142
|
+
? EciesEncryptionTypeEnum.Simple
|
|
143
|
+
: EciesEncryptionTypeEnum.Single,
|
|
144
|
+
privateKey,
|
|
145
|
+
encryptedData,
|
|
146
|
+
preambleSize,
|
|
147
|
+
options,
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* Extended decrypt with header
|
|
153
|
+
*/
|
|
154
|
+
public async decryptSimpleOrSingleWithHeaderEx(
|
|
155
|
+
encryptionType: EciesEncryptionTypeEnum,
|
|
156
|
+
privateKey: Uint8Array,
|
|
157
|
+
encryptedData: Uint8Array,
|
|
158
|
+
preambleSize: number = 0,
|
|
159
|
+
options?: { dataLength?: number },
|
|
160
|
+
) {
|
|
161
|
+
return this.singleRecipient.decryptWithHeaderEx(
|
|
162
|
+
encryptionType,
|
|
163
|
+
privateKey,
|
|
164
|
+
encryptedData,
|
|
165
|
+
preambleSize,
|
|
166
|
+
options,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Decrypt with individual components
|
|
172
|
+
*/
|
|
173
|
+
public async decryptSingleWithComponents(
|
|
174
|
+
privateKey: Uint8Array,
|
|
175
|
+
ephemeralPublicKey: Uint8Array,
|
|
176
|
+
iv: Uint8Array,
|
|
177
|
+
authTag: Uint8Array,
|
|
178
|
+
encrypted: Uint8Array,
|
|
179
|
+
): Promise<{ decrypted: Uint8Array; ciphertextLength?: number }> {
|
|
180
|
+
const decrypted = await this.singleRecipient.decryptWithComponents(
|
|
181
|
+
privateKey,
|
|
182
|
+
ephemeralPublicKey,
|
|
183
|
+
iv,
|
|
184
|
+
authTag,
|
|
185
|
+
encrypted,
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
return { decrypted, ciphertextLength: encrypted.length };
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// === Signature Methods ===
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Sign a message
|
|
195
|
+
*/
|
|
196
|
+
public signMessage(
|
|
197
|
+
privateKey: Uint8Array,
|
|
198
|
+
data: Uint8Array,
|
|
199
|
+
): SignatureUint8Array {
|
|
200
|
+
return this.signature.signMessage(privateKey, data);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/**
|
|
204
|
+
* Verify a message signature
|
|
205
|
+
*/
|
|
206
|
+
public verifyMessage(
|
|
207
|
+
publicKey: Uint8Array,
|
|
208
|
+
data: Uint8Array,
|
|
209
|
+
signature: SignatureUint8Array,
|
|
210
|
+
): boolean {
|
|
211
|
+
return this.signature.verifyMessage(publicKey, data, signature);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Convert signature string to buffer
|
|
216
|
+
*/
|
|
217
|
+
public signatureStringToSignatureUint8Array(
|
|
218
|
+
signatureString: SignatureString,
|
|
219
|
+
): SignatureUint8Array {
|
|
220
|
+
return this.signature.signatureStringToSignatureUint8Array(signatureString);
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Convert signature buffer to string
|
|
225
|
+
*/
|
|
226
|
+
public signatureUint8ArrayToSignatureString(
|
|
227
|
+
signatureArray: SignatureUint8Array,
|
|
228
|
+
): string {
|
|
229
|
+
return this.signature.signatureUint8ArrayToSignatureString(signatureArray);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// === Utility Methods ===
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Compute encrypted length from data length
|
|
236
|
+
*/
|
|
237
|
+
public computeEncryptedLengthFromDataLength(
|
|
238
|
+
dataLength: number,
|
|
239
|
+
encryptionMode: EciesEncryptionType,
|
|
240
|
+
recipientCount?: number,
|
|
241
|
+
): number {
|
|
242
|
+
if (dataLength < 0) {
|
|
243
|
+
throw new Error('Invalid data length');
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
switch (encryptionMode) {
|
|
247
|
+
case 'simple':
|
|
248
|
+
return dataLength + this.eciesConsts.SIMPLE.FIXED_OVERHEAD_SIZE;
|
|
249
|
+
case 'single':
|
|
250
|
+
return dataLength + this.eciesConsts.SINGLE.FIXED_OVERHEAD_SIZE;
|
|
251
|
+
case 'multiple':
|
|
252
|
+
// Basic calculation for multiple recipients
|
|
253
|
+
return (
|
|
254
|
+
dataLength +
|
|
255
|
+
this.eciesConsts.MULTIPLE.FIXED_OVERHEAD_SIZE +
|
|
256
|
+
(recipientCount ?? 1) * this.eciesConsts.MULTIPLE.ENCRYPTED_KEY_SIZE
|
|
257
|
+
);
|
|
258
|
+
default:
|
|
259
|
+
throw new Error('Invalid encryption type');
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Compute decrypted length from encrypted data length
|
|
265
|
+
*/
|
|
266
|
+
public computeDecryptedLengthFromEncryptedDataLength(
|
|
267
|
+
encryptedDataLength: number,
|
|
268
|
+
padding?: number,
|
|
269
|
+
): number {
|
|
270
|
+
if (encryptedDataLength < 0) {
|
|
271
|
+
throw new Error('Invalid encrypted data length');
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
const overhead = this.eciesConsts.SINGLE.FIXED_OVERHEAD_SIZE;
|
|
275
|
+
const actualPadding = padding !== undefined ? padding : 0;
|
|
276
|
+
const decryptedLength = encryptedDataLength - overhead - actualPadding;
|
|
277
|
+
|
|
278
|
+
if (decryptedLength < 0) {
|
|
279
|
+
throw new Error('Computed decrypted length is negative');
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
return decryptedLength;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Generic encrypt method
|
|
287
|
+
*/
|
|
288
|
+
public async encrypt(
|
|
289
|
+
encryptionType: EciesEncryptionTypeEnum,
|
|
290
|
+
recipients: Array<{ publicKey: Uint8Array }>,
|
|
291
|
+
message: Uint8Array,
|
|
292
|
+
preamble?: Uint8Array,
|
|
293
|
+
): Promise<Uint8Array> {
|
|
294
|
+
if (
|
|
295
|
+
(encryptionType === EciesEncryptionTypeEnum.Simple ||
|
|
296
|
+
EciesEncryptionTypeEnum.Single) &&
|
|
297
|
+
recipients.length === 1
|
|
298
|
+
) {
|
|
299
|
+
return this.singleRecipient.encrypt(
|
|
300
|
+
encryptionType === EciesEncryptionTypeEnum.Simple,
|
|
301
|
+
recipients[0].publicKey,
|
|
302
|
+
message,
|
|
303
|
+
preamble,
|
|
304
|
+
);
|
|
305
|
+
} else if (
|
|
306
|
+
encryptionType === EciesEncryptionTypeEnum.Multiple &&
|
|
307
|
+
recipients.length > 1
|
|
308
|
+
) {
|
|
309
|
+
// TODO: Implement multi-recipient encryption
|
|
310
|
+
throw new Error('Multi-recipient encryption not yet implemented');
|
|
311
|
+
} else {
|
|
312
|
+
throw new Error(
|
|
313
|
+
`Invalid encryption type or number of recipients: ${encryptionType}, ${recipients.length}`,
|
|
314
|
+
);
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
}
|