@digitaldefiance/ecies-lib 4.4.2 → 4.4.3
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/LICENSE +21 -0
- package/package.json +9 -6
- package/src/builders/ecies-builder.ts +39 -0
- package/src/builders/{index.js → index.ts} +1 -1
- package/src/builders/member-builder.ts +155 -0
- package/src/constants.ts +609 -0
- package/src/core/errors/crypto-error.ts +78 -0
- package/src/core/{index.js → index.ts} +1 -1
- package/src/core/types/result.ts +19 -0
- package/src/email-string.ts +82 -0
- package/src/enumerations/disposed-error-type.ts +11 -0
- package/src/enumerations/ecies-cipher-suite.ts +4 -0
- package/src/enumerations/ecies-encryption-type.ts +41 -0
- package/src/enumerations/ecies-error-type.ts +43 -0
- package/src/enumerations/ecies-string-key.ts +205 -0
- package/src/enumerations/ecies-version.ts +3 -0
- package/src/enumerations/guid-brand-type.ts +26 -0
- package/src/enumerations/guid-error-type.ts +6 -0
- package/src/enumerations/id-provider-error-type.ts +50 -0
- package/src/enumerations/{index.js → 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/src/enumerations/{member-type.d.ts → 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 +36 -0
- package/src/errors/ecies.ts +153 -0
- package/src/errors/guid.ts +130 -0
- package/src/errors/id-provider.ts +40 -0
- package/src/errors/{index.d.ts → index.ts} +0 -1
- package/src/errors/invalid-email.ts +23 -0
- package/src/errors/length.ts +19 -0
- package/src/errors/member.ts +20 -0
- package/src/errors/pbkdf2.ts +20 -0
- package/src/errors/secure-storage.ts +17 -0
- package/src/errors/simple-ecies.ts +21 -0
- package/src/errors/simple-test-error.ts +6 -0
- package/src/i18n-setup.ts +130 -0
- package/src/{index.js → index.ts} +64 -7
- package/src/interfaces/checksum-config.ts +4 -0
- package/src/interfaces/checksum-consts.ts +13 -0
- package/src/interfaces/configuration-provenance.ts +54 -0
- package/src/interfaces/constants.ts +75 -0
- package/src/interfaces/ecies-config.ts +8 -0
- package/src/interfaces/ecies-consts.ts +74 -0
- package/src/interfaces/ecies-file-service.ts +6 -0
- package/src/interfaces/encrypted-chunk.ts +64 -0
- package/src/interfaces/encryption-state.ts +19 -0
- package/src/interfaces/frontend-member-operational.ts +77 -0
- package/src/interfaces/guid.ts +86 -0
- package/src/interfaces/id-provider.ts +152 -0
- package/src/interfaces/{index.d.ts → index.ts} +0 -1
- package/src/interfaces/invariant.ts +60 -0
- package/src/interfaces/library-error.ts +23 -0
- package/src/interfaces/{member-storage.d.ts → member-storage.ts} +11 -10
- package/src/interfaces/{member-with-mnemonic.d.ts → member-with-mnemonic.ts} +3 -3
- package/src/interfaces/member.ts +84 -0
- package/src/interfaces/multi-recipient-chunk.ts +61 -0
- 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/interfaces/stream-config.ts +17 -0
- package/src/interfaces/stream-header.ts +34 -0
- package/src/interfaces/stream-progress.ts +31 -0
- package/src/lib/configuration-provenance-utils.ts +26 -0
- package/src/lib/crypto-container.ts +64 -0
- package/src/lib/guid.ts +1097 -0
- package/src/lib/id-providers/custom-provider.ts +109 -0
- package/src/lib/id-providers/guidv4-provider.ts +141 -0
- package/src/lib/id-providers/{index.d.ts → index.ts} +6 -5
- package/src/lib/id-providers/objectid-provider.ts +125 -0
- package/src/lib/id-providers/uuid-provider.ts +133 -0
- package/src/lib/{index.js → index.ts} +2 -2
- package/src/lib/invariant-validator.ts +133 -0
- package/src/lib/invariants/encryption-algorithm-consistency.ts +73 -0
- package/src/lib/invariants/{index.js → index.ts} +0 -1
- package/src/lib/invariants/pbkdf2-profiles-validity.ts +78 -0
- package/src/lib/invariants/recipient-id-consistency.ts +46 -0
- package/src/lib/multi-recipient-chunk-utils.ts +63 -0
- package/src/member.ts +495 -0
- package/src/{pbkdf2-profiles.d.ts → pbkdf2-profiles.ts} +2 -2
- package/src/phone-number.ts +18 -0
- package/src/regexes.ts +10 -0
- package/src/secure-buffer.ts +226 -0
- package/src/secure-string.ts +244 -0
- package/src/services/aes-gcm.ts +220 -0
- package/src/services/chunk-processor.ts +188 -0
- package/src/services/ecies/README.md +147 -0
- package/src/services/ecies/crypto-core.ts +292 -0
- package/src/services/ecies/example.ts +185 -0
- package/src/services/ecies/file.ts +167 -0
- package/src/services/ecies/{index.js → index.ts} +2 -1
- package/src/services/ecies/integration.ts +241 -0
- package/src/services/ecies/interfaces.ts +62 -0
- package/src/services/ecies/manual-test.ts +219 -0
- package/src/services/ecies/multi-recipient.ts +545 -0
- package/src/services/ecies/service.ts +370 -0
- package/src/services/ecies/signature.ts +93 -0
- package/src/services/ecies/single-recipient.ts +476 -0
- package/src/services/encryption-stream.ts +435 -0
- package/src/services/{index.js → index.ts} +0 -1
- package/src/services/multi-recipient-processor.ts +377 -0
- package/src/services/password-login.ts +226 -0
- package/src/services/pbkdf2.ts +169 -0
- package/src/services/progress-tracker.ts +128 -0
- package/src/services/resumable-encryption.ts +135 -0
- package/src/services/xor.ts +65 -0
- package/src/test-mocks/index.ts +1 -0
- package/src/test-mocks/mock-frontend-member.ts +276 -0
- package/src/{testing.js → testing.ts} +0 -1
- package/src/translations/{de.js → de.ts} +112 -56
- package/src/translations/{en-US.js → en-US.ts} +116 -58
- package/src/translations/{es.js → es.ts} +134 -67
- package/src/translations/{fr.js → fr.ts} +129 -64
- package/src/translations/{ja.js → ja.ts} +111 -55
- package/src/translations/{uk.js → uk.ts} +132 -67
- package/src/translations/{zh-cn.js → zh-cn.ts} +60 -29
- package/src/types/deep-partial.ts +11 -0
- package/src/{types.d.ts → types.ts} +15 -7
- package/src/utils/encryption-type-utils.ts +76 -0
- package/src/utils.ts +329 -0
- package/src/builders/ecies-builder.d.ts +0 -18
- package/src/builders/ecies-builder.d.ts.map +0 -1
- package/src/builders/ecies-builder.js +0 -30
- package/src/builders/ecies-builder.js.map +0 -1
- package/src/builders/index.d.ts +0 -6
- package/src/builders/index.d.ts.map +0 -1
- package/src/builders/index.js.map +0 -1
- package/src/builders/member-builder.d.ts +0 -51
- package/src/builders/member-builder.d.ts.map +0 -1
- package/src/builders/member-builder.js +0 -97
- package/src/builders/member-builder.js.map +0 -1
- package/src/constants.d.ts +0 -60
- package/src/constants.d.ts.map +0 -1
- package/src/constants.js +0 -446
- package/src/constants.js.map +0 -1
- package/src/core/errors/crypto-error.d.ts +0 -34
- package/src/core/errors/crypto-error.d.ts.map +0 -1
- package/src/core/errors/crypto-error.js +0 -56
- package/src/core/errors/crypto-error.js.map +0 -1
- package/src/core/index.d.ts +0 -6
- package/src/core/index.d.ts.map +0 -1
- package/src/core/index.js.map +0 -1
- package/src/core/types/result.d.ts +0 -16
- package/src/core/types/result.d.ts.map +0 -1
- package/src/core/types/result.js +0 -12
- package/src/core/types/result.js.map +0 -1
- package/src/email-string.d.ts +0 -42
- package/src/email-string.d.ts.map +0 -1
- package/src/email-string.js +0 -67
- package/src/email-string.js.map +0 -1
- package/src/enumerations/disposed-error-type.d.ts +0 -12
- package/src/enumerations/disposed-error-type.d.ts.map +0 -1
- package/src/enumerations/disposed-error-type.js +0 -13
- package/src/enumerations/disposed-error-type.js.map +0 -1
- package/src/enumerations/ecies-cipher-suite.d.ts +0 -4
- package/src/enumerations/ecies-cipher-suite.d.ts.map +0 -1
- package/src/enumerations/ecies-cipher-suite.js +0 -6
- package/src/enumerations/ecies-cipher-suite.js.map +0 -1
- package/src/enumerations/ecies-encryption-type.d.ts +0 -11
- package/src/enumerations/ecies-encryption-type.d.ts.map +0 -1
- package/src/enumerations/ecies-encryption-type.js +0 -27
- package/src/enumerations/ecies-encryption-type.js.map +0 -1
- package/src/enumerations/ecies-error-type.d.ts +0 -44
- package/src/enumerations/ecies-error-type.d.ts.map +0 -1
- package/src/enumerations/ecies-error-type.js +0 -45
- package/src/enumerations/ecies-error-type.js.map +0 -1
- package/src/enumerations/ecies-string-key.d.ts +0 -192
- package/src/enumerations/ecies-string-key.d.ts.map +0 -1
- package/src/enumerations/ecies-string-key.js +0 -199
- package/src/enumerations/ecies-string-key.js.map +0 -1
- package/src/enumerations/ecies-version.d.ts +0 -4
- package/src/enumerations/ecies-version.d.ts.map +0 -1
- package/src/enumerations/ecies-version.js +0 -5
- package/src/enumerations/ecies-version.js.map +0 -1
- package/src/enumerations/guid-brand-type.d.ts +0 -27
- package/src/enumerations/guid-brand-type.d.ts.map +0 -1
- package/src/enumerations/guid-brand-type.js +0 -28
- package/src/enumerations/guid-brand-type.js.map +0 -1
- package/src/enumerations/guid-error-type.d.ts +0 -7
- package/src/enumerations/guid-error-type.d.ts.map +0 -1
- package/src/enumerations/guid-error-type.js +0 -8
- package/src/enumerations/guid-error-type.js.map +0 -1
- package/src/enumerations/id-provider-error-type.d.ts +0 -43
- package/src/enumerations/id-provider-error-type.d.ts.map +0 -1
- package/src/enumerations/id-provider-error-type.js +0 -44
- package/src/enumerations/id-provider-error-type.js.map +0 -1
- package/src/enumerations/index.d.ts +0 -18
- package/src/enumerations/index.d.ts.map +0 -1
- package/src/enumerations/index.js.map +0 -1
- package/src/enumerations/invalid-email-type.d.ts +0 -6
- package/src/enumerations/invalid-email-type.d.ts.map +0 -1
- package/src/enumerations/invalid-email-type.js +0 -7
- package/src/enumerations/invalid-email-type.js.map +0 -1
- package/src/enumerations/length-encoding-type.d.ts +0 -7
- package/src/enumerations/length-encoding-type.d.ts.map +0 -1
- package/src/enumerations/length-encoding-type.js +0 -8
- package/src/enumerations/length-encoding-type.js.map +0 -1
- package/src/enumerations/length-error-type.d.ts +0 -6
- package/src/enumerations/length-error-type.d.ts.map +0 -1
- package/src/enumerations/length-error-type.js +0 -7
- package/src/enumerations/length-error-type.js.map +0 -1
- package/src/enumerations/member-error-type.d.ts +0 -87
- package/src/enumerations/member-error-type.d.ts.map +0 -1
- package/src/enumerations/member-error-type.js +0 -88
- package/src/enumerations/member-error-type.js.map +0 -1
- package/src/enumerations/member-type.d.ts.map +0 -1
- package/src/enumerations/member-type.js +0 -16
- package/src/enumerations/member-type.js.map +0 -1
- package/src/enumerations/password-login-error-type.d.ts +0 -5
- package/src/enumerations/password-login-error-type.d.ts.map +0 -1
- package/src/enumerations/password-login-error-type.js +0 -6
- package/src/enumerations/password-login-error-type.js.map +0 -1
- package/src/enumerations/pbkdf2-error-type.d.ts +0 -6
- package/src/enumerations/pbkdf2-error-type.d.ts.map +0 -1
- package/src/enumerations/pbkdf2-error-type.js +0 -7
- package/src/enumerations/pbkdf2-error-type.js.map +0 -1
- package/src/enumerations/pbkdf2-profile.d.ts +0 -6
- package/src/enumerations/pbkdf2-profile.d.ts.map +0 -1
- package/src/enumerations/pbkdf2-profile.js +0 -7
- package/src/enumerations/pbkdf2-profile.js.map +0 -1
- package/src/enumerations/secure-storage-error-type.d.ts +0 -6
- package/src/enumerations/secure-storage-error-type.d.ts.map +0 -1
- package/src/enumerations/secure-storage-error-type.js +0 -7
- package/src/enumerations/secure-storage-error-type.js.map +0 -1
- package/src/errors/disposed.d.ts +0 -22
- package/src/errors/disposed.d.ts.map +0 -1
- package/src/errors/disposed.js +0 -28
- package/src/errors/disposed.js.map +0 -1
- package/src/errors/ecies.d.ts +0 -52
- package/src/errors/ecies.d.ts.map +0 -1
- package/src/errors/ecies.js +0 -78
- package/src/errors/ecies.js.map +0 -1
- package/src/errors/guid.d.ts +0 -49
- package/src/errors/guid.d.ts.map +0 -1
- package/src/errors/guid.js +0 -96
- package/src/errors/guid.js.map +0 -1
- package/src/errors/id-provider.d.ts +0 -23
- package/src/errors/id-provider.d.ts.map +0 -1
- package/src/errors/id-provider.js +0 -29
- package/src/errors/id-provider.js.map +0 -1
- package/src/errors/index.d.ts.map +0 -1
- package/src/errors/index.js +0 -10
- package/src/errors/index.js.map +0 -1
- package/src/errors/invalid-email.d.ts +0 -8
- package/src/errors/invalid-email.d.ts.map +0 -1
- package/src/errors/invalid-email.js +0 -15
- package/src/errors/invalid-email.js.map +0 -1
- package/src/errors/length.d.ts +0 -7
- package/src/errors/length.d.ts.map +0 -1
- package/src/errors/length.js +0 -11
- package/src/errors/length.js.map +0 -1
- package/src/errors/member.d.ts +0 -7
- package/src/errors/member.d.ts.map +0 -1
- package/src/errors/member.js +0 -11
- package/src/errors/member.js.map +0 -1
- package/src/errors/pbkdf2.d.ts +0 -7
- package/src/errors/pbkdf2.d.ts.map +0 -1
- package/src/errors/pbkdf2.js +0 -11
- package/src/errors/pbkdf2.js.map +0 -1
- package/src/errors/secure-storage.d.ts +0 -7
- package/src/errors/secure-storage.d.ts.map +0 -1
- package/src/errors/secure-storage.js +0 -12
- package/src/errors/secure-storage.js.map +0 -1
- package/src/errors/simple-ecies.d.ts +0 -6
- package/src/errors/simple-ecies.d.ts.map +0 -1
- package/src/errors/simple-ecies.js +0 -12
- package/src/errors/simple-ecies.js.map +0 -1
- package/src/errors/simple-test-error.d.ts +0 -4
- package/src/errors/simple-test-error.d.ts.map +0 -1
- package/src/errors/simple-test-error.js +0 -7
- package/src/errors/simple-test-error.js.map +0 -1
- package/src/i18n-setup.d.ts +0 -32
- package/src/i18n-setup.d.ts.map +0 -1
- package/src/i18n-setup.js +0 -101
- package/src/i18n-setup.js.map +0 -1
- package/src/index.d.ts +0 -80
- package/src/index.d.ts.map +0 -1
- package/src/index.js.map +0 -1
- package/src/interfaces/checksum-config.d.ts +0 -5
- package/src/interfaces/checksum-config.d.ts.map +0 -1
- package/src/interfaces/checksum-config.js +0 -2
- package/src/interfaces/checksum-config.js.map +0 -1
- package/src/interfaces/checksum-consts.d.ts +0 -11
- package/src/interfaces/checksum-consts.d.ts.map +0 -1
- package/src/interfaces/checksum-consts.js +0 -2
- package/src/interfaces/checksum-consts.js.map +0 -1
- package/src/interfaces/configuration-provenance.d.ts +0 -43
- package/src/interfaces/configuration-provenance.d.ts.map +0 -1
- package/src/interfaces/configuration-provenance.js +0 -3
- package/src/interfaces/configuration-provenance.js.map +0 -1
- package/src/interfaces/constants.d.ts +0 -70
- package/src/interfaces/constants.d.ts.map +0 -1
- package/src/interfaces/constants.js +0 -2
- package/src/interfaces/constants.js.map +0 -1
- package/src/interfaces/ecies-config.d.ts +0 -9
- package/src/interfaces/ecies-config.d.ts.map +0 -1
- package/src/interfaces/ecies-config.js +0 -2
- package/src/interfaces/ecies-config.js.map +0 -1
- package/src/interfaces/ecies-consts.d.ts +0 -61
- package/src/interfaces/ecies-consts.d.ts.map +0 -1
- package/src/interfaces/ecies-consts.js +0 -2
- package/src/interfaces/ecies-consts.js.map +0 -1
- package/src/interfaces/ecies-file-service.d.ts +0 -7
- package/src/interfaces/ecies-file-service.d.ts.map +0 -1
- package/src/interfaces/ecies-file-service.js +0 -2
- package/src/interfaces/ecies-file-service.js.map +0 -1
- package/src/interfaces/encrypted-chunk.d.ts +0 -55
- package/src/interfaces/encrypted-chunk.d.ts.map +0 -1
- package/src/interfaces/encrypted-chunk.js +0 -12
- package/src/interfaces/encrypted-chunk.js.map +0 -1
- package/src/interfaces/encryption-state.d.ts +0 -18
- package/src/interfaces/encryption-state.d.ts.map +0 -1
- package/src/interfaces/encryption-state.js +0 -2
- package/src/interfaces/encryption-state.js.map +0 -1
- package/src/interfaces/frontend-member-operational.d.ts +0 -51
- package/src/interfaces/frontend-member-operational.d.ts.map +0 -1
- package/src/interfaces/frontend-member-operational.js +0 -2
- package/src/interfaces/frontend-member-operational.js.map +0 -1
- package/src/interfaces/guid.d.ts +0 -78
- package/src/interfaces/guid.d.ts.map +0 -1
- package/src/interfaces/guid.js +0 -2
- package/src/interfaces/guid.js.map +0 -1
- package/src/interfaces/id-provider.d.ts +0 -107
- package/src/interfaces/id-provider.d.ts.map +0 -1
- package/src/interfaces/id-provider.js +0 -52
- package/src/interfaces/id-provider.js.map +0 -1
- package/src/interfaces/index.d.ts.map +0 -1
- package/src/interfaces/index.js +0 -13
- package/src/interfaces/index.js.map +0 -1
- package/src/interfaces/invariant.d.ts +0 -46
- package/src/interfaces/invariant.d.ts.map +0 -1
- package/src/interfaces/invariant.js +0 -18
- package/src/interfaces/invariant.js.map +0 -1
- package/src/interfaces/library-error.d.ts +0 -23
- package/src/interfaces/library-error.d.ts.map +0 -1
- package/src/interfaces/library-error.js +0 -2
- package/src/interfaces/library-error.js.map +0 -1
- package/src/interfaces/member-storage.d.ts.map +0 -1
- package/src/interfaces/member-storage.js +0 -2
- package/src/interfaces/member-storage.js.map +0 -1
- package/src/interfaces/member-with-mnemonic.d.ts.map +0 -1
- package/src/interfaces/member-with-mnemonic.js +0 -2
- package/src/interfaces/member-with-mnemonic.js.map +0 -1
- package/src/interfaces/member.d.ts +0 -55
- package/src/interfaces/member.d.ts.map +0 -1
- package/src/interfaces/member.js +0 -2
- package/src/interfaces/member.js.map +0 -1
- package/src/interfaces/multi-recipient-chunk.d.ts +0 -54
- package/src/interfaces/multi-recipient-chunk.d.ts.map +0 -1
- package/src/interfaces/multi-recipient-chunk.js +0 -11
- package/src/interfaces/multi-recipient-chunk.js.map +0 -1
- package/src/interfaces/pbkdf2-config.d.ts +0 -7
- package/src/interfaces/pbkdf2-config.d.ts.map +0 -1
- package/src/interfaces/pbkdf2-config.js +0 -2
- package/src/interfaces/pbkdf2-config.js.map +0 -1
- package/src/interfaces/pbkdf2-consts.d.ts +0 -9
- package/src/interfaces/pbkdf2-consts.d.ts.map +0 -1
- package/src/interfaces/pbkdf2-consts.js +0 -2
- package/src/interfaces/pbkdf2-consts.js.map +0 -1
- package/src/interfaces/pbkdf2-result.d.ts +0 -6
- package/src/interfaces/pbkdf2-result.d.ts.map +0 -1
- package/src/interfaces/pbkdf2-result.js +0 -2
- package/src/interfaces/pbkdf2-result.js.map +0 -1
- package/src/interfaces/stream-config.d.ts +0 -14
- package/src/interfaces/stream-config.d.ts.map +0 -1
- package/src/interfaces/stream-config.js +0 -8
- package/src/interfaces/stream-config.js.map +0 -1
- package/src/interfaces/stream-header.d.ts +0 -29
- package/src/interfaces/stream-header.d.ts.map +0 -1
- package/src/interfaces/stream-header.js +0 -9
- package/src/interfaces/stream-header.js.map +0 -1
- package/src/interfaces/stream-progress.d.ts +0 -33
- package/src/interfaces/stream-progress.d.ts.map +0 -1
- package/src/interfaces/stream-progress.js +0 -2
- package/src/interfaces/stream-progress.js.map +0 -1
- package/src/lib/configuration-provenance-utils.d.ts +0 -11
- package/src/lib/configuration-provenance-utils.d.ts.map +0 -1
- package/src/lib/configuration-provenance-utils.js +0 -23
- package/src/lib/configuration-provenance-utils.js.map +0 -1
- package/src/lib/crypto-container.d.ts +0 -25
- package/src/lib/crypto-container.d.ts.map +0 -1
- package/src/lib/crypto-container.js +0 -46
- package/src/lib/crypto-container.js.map +0 -1
- package/src/lib/guid.d.ts +0 -344
- package/src/lib/guid.d.ts.map +0 -1
- package/src/lib/guid.js +0 -914
- package/src/lib/guid.js.map +0 -1
- package/src/lib/id-providers/custom-provider.d.ts +0 -46
- package/src/lib/id-providers/custom-provider.d.ts.map +0 -1
- package/src/lib/id-providers/custom-provider.js +0 -85
- package/src/lib/id-providers/custom-provider.js.map +0 -1
- package/src/lib/id-providers/guidv4-provider.d.ts +0 -56
- package/src/lib/id-providers/guidv4-provider.d.ts.map +0 -1
- package/src/lib/id-providers/guidv4-provider.js +0 -122
- package/src/lib/id-providers/guidv4-provider.js.map +0 -1
- package/src/lib/id-providers/index.d.ts.map +0 -1
- package/src/lib/id-providers/index.js +0 -29
- package/src/lib/id-providers/index.js.map +0 -1
- package/src/lib/id-providers/objectid-provider.d.ts +0 -43
- package/src/lib/id-providers/objectid-provider.d.ts.map +0 -1
- package/src/lib/id-providers/objectid-provider.js +0 -104
- package/src/lib/id-providers/objectid-provider.js.map +0 -1
- package/src/lib/id-providers/uuid-provider.d.ts +0 -52
- package/src/lib/id-providers/uuid-provider.d.ts.map +0 -1
- package/src/lib/id-providers/uuid-provider.js +0 -110
- package/src/lib/id-providers/uuid-provider.js.map +0 -1
- package/src/lib/index.d.ts +0 -6
- package/src/lib/index.d.ts.map +0 -1
- package/src/lib/index.js.map +0 -1
- package/src/lib/invariant-validator.d.ts +0 -59
- package/src/lib/invariant-validator.d.ts.map +0 -1
- package/src/lib/invariant-validator.js +0 -97
- package/src/lib/invariant-validator.js.map +0 -1
- package/src/lib/invariants/encryption-algorithm-consistency.d.ts +0 -17
- package/src/lib/invariants/encryption-algorithm-consistency.d.ts.map +0 -1
- package/src/lib/invariants/encryption-algorithm-consistency.js +0 -49
- package/src/lib/invariants/encryption-algorithm-consistency.js.map +0 -1
- package/src/lib/invariants/index.d.ts +0 -4
- package/src/lib/invariants/index.d.ts.map +0 -1
- package/src/lib/invariants/index.js.map +0 -1
- package/src/lib/invariants/pbkdf2-profiles-validity.d.ts +0 -16
- package/src/lib/invariants/pbkdf2-profiles-validity.d.ts.map +0 -1
- package/src/lib/invariants/pbkdf2-profiles-validity.js +0 -58
- package/src/lib/invariants/pbkdf2-profiles-validity.js.map +0 -1
- package/src/lib/invariants/recipient-id-consistency.d.ts +0 -18
- package/src/lib/invariants/recipient-id-consistency.d.ts.map +0 -1
- package/src/lib/invariants/recipient-id-consistency.js +0 -31
- package/src/lib/invariants/recipient-id-consistency.js.map +0 -1
- package/src/lib/multi-recipient-chunk-utils.d.ts +0 -38
- package/src/lib/multi-recipient-chunk-utils.d.ts.map +0 -1
- package/src/lib/multi-recipient-chunk-utils.js +0 -41
- package/src/lib/multi-recipient-chunk-utils.js.map +0 -1
- package/src/member.d.ts +0 -92
- package/src/member.d.ts.map +0 -1
- package/src/member.js +0 -322
- package/src/member.js.map +0 -1
- package/src/pbkdf2-profiles.d.ts.map +0 -1
- package/src/pbkdf2-profiles.js +0 -2
- package/src/pbkdf2-profiles.js.map +0 -1
- package/src/phone-number.d.ts +0 -6
- package/src/phone-number.d.ts.map +0 -1
- package/src/phone-number.js +0 -18
- package/src/phone-number.js.map +0 -1
- package/src/regexes.d.ts +0 -7
- package/src/regexes.d.ts.map +0 -1
- package/src/regexes.js +0 -7
- package/src/regexes.js.map +0 -1
- package/src/secure-buffer.d.ts +0 -61
- package/src/secure-buffer.d.ts.map +0 -1
- package/src/secure-buffer.js +0 -201
- package/src/secure-buffer.js.map +0 -1
- package/src/secure-string.d.ts +0 -46
- package/src/secure-string.d.ts.map +0 -1
- package/src/secure-string.js +0 -206
- package/src/secure-string.js.map +0 -1
- package/src/services/aes-gcm.d.ts +0 -57
- package/src/services/aes-gcm.d.ts.map +0 -1
- package/src/services/aes-gcm.js +0 -142
- package/src/services/aes-gcm.js.map +0 -1
- package/src/services/chunk-processor.d.ts +0 -31
- package/src/services/chunk-processor.d.ts.map +0 -1
- package/src/services/chunk-processor.js +0 -145
- package/src/services/chunk-processor.js.map +0 -1
- package/src/services/ecies/crypto-core.d.ts +0 -72
- package/src/services/ecies/crypto-core.d.ts.map +0 -1
- package/src/services/ecies/crypto-core.js +0 -205
- package/src/services/ecies/crypto-core.js.map +0 -1
- package/src/services/ecies/example.d.ts +0 -25
- package/src/services/ecies/example.d.ts.map +0 -1
- package/src/services/ecies/example.js +0 -121
- package/src/services/ecies/example.js.map +0 -1
- package/src/services/ecies/file.d.ts +0 -18
- package/src/services/ecies/file.d.ts.map +0 -1
- package/src/services/ecies/file.js +0 -106
- package/src/services/ecies/file.js.map +0 -1
- package/src/services/ecies/index.d.ts +0 -38
- package/src/services/ecies/index.d.ts.map +0 -1
- package/src/services/ecies/index.js.map +0 -1
- package/src/services/ecies/integration.d.ts +0 -59
- package/src/services/ecies/integration.d.ts.map +0 -1
- package/src/services/ecies/integration.js +0 -167
- package/src/services/ecies/integration.js.map +0 -1
- package/src/services/ecies/interfaces.d.ts +0 -54
- package/src/services/ecies/interfaces.d.ts.map +0 -1
- package/src/services/ecies/interfaces.js +0 -5
- package/src/services/ecies/interfaces.js.map +0 -1
- package/src/services/ecies/manual-test.d.ts +0 -29
- package/src/services/ecies/manual-test.d.ts.map +0 -1
- package/src/services/ecies/manual-test.js +0 -163
- package/src/services/ecies/manual-test.js.map +0 -1
- package/src/services/ecies/multi-recipient.d.ts +0 -56
- package/src/services/ecies/multi-recipient.d.ts.map +0 -1
- package/src/services/ecies/multi-recipient.js +0 -344
- package/src/services/ecies/multi-recipient.js.map +0 -1
- package/src/services/ecies/service.d.ts +0 -120
- package/src/services/ecies/service.d.ts.map +0 -1
- package/src/services/ecies/service.js +0 -210
- package/src/services/ecies/service.js.map +0 -1
- package/src/services/ecies/signature.d.ts +0 -27
- package/src/services/ecies/signature.d.ts.map +0 -1
- package/src/services/ecies/signature.js +0 -72
- package/src/services/ecies/signature.js.map +0 -1
- package/src/services/ecies/single-recipient.d.ts +0 -46
- package/src/services/ecies/single-recipient.d.ts.map +0 -1
- package/src/services/ecies/single-recipient.js +0 -322
- package/src/services/ecies/single-recipient.js.map +0 -1
- package/src/services/encryption-stream.d.ts +0 -71
- package/src/services/encryption-stream.d.ts.map +0 -1
- package/src/services/encryption-stream.js +0 -295
- package/src/services/encryption-stream.js.map +0 -1
- package/src/services/index.d.ts +0 -11
- package/src/services/index.d.ts.map +0 -1
- package/src/services/index.js.map +0 -1
- package/src/services/multi-recipient-processor.d.ts +0 -35
- package/src/services/multi-recipient-processor.d.ts.map +0 -1
- package/src/services/multi-recipient-processor.js +0 -289
- package/src/services/multi-recipient-processor.js.map +0 -1
- package/src/services/password-login.d.ts +0 -47
- package/src/services/password-login.d.ts.map +0 -1
- package/src/services/password-login.js +0 -115
- package/src/services/password-login.js.map +0 -1
- package/src/services/pbkdf2.d.ts +0 -54
- package/src/services/pbkdf2.d.ts.map +0 -1
- package/src/services/pbkdf2.js +0 -108
- package/src/services/pbkdf2.js.map +0 -1
- package/src/services/progress-tracker.d.ts +0 -23
- package/src/services/progress-tracker.d.ts.map +0 -1
- package/src/services/progress-tracker.js +0 -103
- package/src/services/progress-tracker.js.map +0 -1
- package/src/services/resumable-encryption.d.ts +0 -19
- package/src/services/resumable-encryption.d.ts.map +0 -1
- package/src/services/resumable-encryption.js +0 -105
- package/src/services/resumable-encryption.js.map +0 -1
- package/src/services/xor.d.ts +0 -37
- package/src/services/xor.d.ts.map +0 -1
- package/src/services/xor.js +0 -63
- package/src/services/xor.js.map +0 -1
- package/src/test-mocks/index.d.ts +0 -2
- package/src/test-mocks/index.d.ts.map +0 -1
- package/src/test-mocks/index.js +0 -2
- package/src/test-mocks/index.js.map +0 -1
- package/src/test-mocks/mock-frontend-member.d.ts +0 -85
- package/src/test-mocks/mock-frontend-member.d.ts.map +0 -1
- package/src/test-mocks/mock-frontend-member.js +0 -190
- package/src/test-mocks/mock-frontend-member.js.map +0 -1
- package/src/testing.d.ts +0 -2
- package/src/testing.d.ts.map +0 -1
- package/src/testing.js.map +0 -1
- package/src/translations/de.d.ts +0 -4
- package/src/translations/de.d.ts.map +0 -1
- package/src/translations/de.js.map +0 -1
- package/src/translations/en-US.d.ts +0 -4
- package/src/translations/en-US.d.ts.map +0 -1
- package/src/translations/en-US.js.map +0 -1
- package/src/translations/es.d.ts +0 -4
- package/src/translations/es.d.ts.map +0 -1
- package/src/translations/es.js.map +0 -1
- package/src/translations/fr.d.ts +0 -4
- package/src/translations/fr.d.ts.map +0 -1
- package/src/translations/fr.js.map +0 -1
- package/src/translations/ja.d.ts +0 -4
- package/src/translations/ja.d.ts.map +0 -1
- package/src/translations/ja.js.map +0 -1
- package/src/translations/uk.d.ts +0 -4
- package/src/translations/uk.d.ts.map +0 -1
- package/src/translations/uk.js.map +0 -1
- package/src/translations/zh-cn.d.ts +0 -4
- package/src/translations/zh-cn.d.ts.map +0 -1
- package/src/translations/zh-cn.js.map +0 -1
- package/src/types/deep-partial.d.ts +0 -4
- package/src/types/deep-partial.d.ts.map +0 -1
- package/src/types/deep-partial.js +0 -2
- package/src/types/deep-partial.js.map +0 -1
- package/src/types.d.ts.map +0 -1
- package/src/types.js +0 -2
- package/src/types.js.map +0 -1
- package/src/utils/encryption-type-utils.d.ts +0 -29
- package/src/utils/encryption-type-utils.d.ts.map +0 -1
- package/src/utils/encryption-type-utils.js +0 -61
- package/src/utils/encryption-type-utils.js.map +0 -1
- package/src/utils.d.ts +0 -68
- package/src/utils.d.ts.map +0 -1
- package/src/utils.js +0 -273
- package/src/utils.js.map +0 -1
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { ECIESService } from './ecies/service';
|
|
2
|
+
import {
|
|
3
|
+
IMultiRecipientChunk,
|
|
4
|
+
IMultiRecipientChunkHeader,
|
|
5
|
+
IRecipientHeader,
|
|
6
|
+
IMultiRecipientConstants,
|
|
7
|
+
getMultiRecipientConstants,
|
|
8
|
+
} from '../interfaces/multi-recipient-chunk';
|
|
9
|
+
import { EciesComponentId, getEciesI18nEngine } from '../i18n-setup';
|
|
10
|
+
import { EciesStringKey } from '../enumerations';
|
|
11
|
+
import { Constants } from '../constants';
|
|
12
|
+
import { IConstants } from '../interfaces/constants';
|
|
13
|
+
import { AESGCMService } from './aes-gcm';
|
|
14
|
+
import { concatUint8Arrays } from '../utils';
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Processes multi-recipient chunks using symmetric encryption.
|
|
18
|
+
* Supports dynamic recipient ID sizes based on the configured ID provider.
|
|
19
|
+
*/
|
|
20
|
+
export class MultiRecipientProcessor {
|
|
21
|
+
private readonly recipientIdSize: number;
|
|
22
|
+
private readonly constants: IMultiRecipientConstants;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Create a new multi-recipient processor.
|
|
26
|
+
* @param ecies - ECIES service for key encryption
|
|
27
|
+
* @param config - Configuration containing ID provider (defaults to global Constants)
|
|
28
|
+
*/
|
|
29
|
+
constructor(
|
|
30
|
+
private readonly ecies: ECIESService,
|
|
31
|
+
private readonly config: IConstants = Constants
|
|
32
|
+
) {
|
|
33
|
+
this.recipientIdSize = config.idProvider.byteLength;
|
|
34
|
+
this.constants = getMultiRecipientConstants(this.recipientIdSize);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Encrypt chunk for multiple recipients
|
|
39
|
+
*/
|
|
40
|
+
async encryptChunk(
|
|
41
|
+
data: Uint8Array,
|
|
42
|
+
recipients: Array<{ id: Uint8Array; publicKey: Uint8Array }>,
|
|
43
|
+
chunkIndex: number,
|
|
44
|
+
isLast: boolean,
|
|
45
|
+
symmetricKey: Uint8Array,
|
|
46
|
+
senderPrivateKey?: Uint8Array,
|
|
47
|
+
): Promise<IMultiRecipientChunk> {
|
|
48
|
+
// Validate inputs
|
|
49
|
+
const engine = getEciesI18nEngine();
|
|
50
|
+
if (recipients.length === 0 || recipients.length > this.constants.MAX_RECIPIENTS) {
|
|
51
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_InvalidRecipientCountTemplate, { count: recipients.length }));
|
|
52
|
+
}
|
|
53
|
+
if (symmetricKey.length !== 32) {
|
|
54
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_SymmetricKeyMust32Bytes));
|
|
55
|
+
}
|
|
56
|
+
if (chunkIndex < 0 || chunkIndex > 0xFFFFFFFF) {
|
|
57
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_InvalidChunkIndexTemplate, { index: chunkIndex }));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Sign-then-Encrypt
|
|
61
|
+
let dataToEncrypt = data;
|
|
62
|
+
if (senderPrivateKey) {
|
|
63
|
+
const signature = this.ecies.core.sign(senderPrivateKey, data);
|
|
64
|
+
dataToEncrypt = concatUint8Arrays(signature, data);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
if (dataToEncrypt.length > 0x7FFFFFFF) {
|
|
68
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_DataSizeExceedsMaximumTemplate, { size: dataToEncrypt.length }));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Check for duplicate recipient IDs
|
|
72
|
+
const seenIds = new Set<string>();
|
|
73
|
+
for (const recipient of recipients) {
|
|
74
|
+
const idStr = Buffer.from(recipient.id).toString('hex');
|
|
75
|
+
if (seenIds.has(idStr)) {
|
|
76
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_DuplicateRecipientId));
|
|
77
|
+
}
|
|
78
|
+
seenIds.add(idStr);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Generate ONE ephemeral key pair for all recipients
|
|
82
|
+
const ephemeralKeyPair = await this.ecies.core.generateEphemeralKeyPair();
|
|
83
|
+
|
|
84
|
+
// Build recipient headers
|
|
85
|
+
const recipientHeaders: IRecipientHeader[] = [];
|
|
86
|
+
for (const recipient of recipients) {
|
|
87
|
+
if (recipient.id.length !== this.recipientIdSize) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
`Recipient ID must be ${this.recipientIdSize} bytes (configured by ID provider), got ${recipient.id.length} bytes`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Use Recipient ID as AAD for key encryption
|
|
94
|
+
const encryptedKey = await this.ecies.encryptKey(
|
|
95
|
+
recipient.publicKey,
|
|
96
|
+
symmetricKey,
|
|
97
|
+
ephemeralKeyPair.privateKey,
|
|
98
|
+
recipient.id
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
recipientHeaders.push({
|
|
102
|
+
id: recipient.id,
|
|
103
|
+
keySize: encryptedKey.length,
|
|
104
|
+
encryptedKey,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Calculate sizes with overflow check
|
|
109
|
+
let recipientHeadersSize = 0;
|
|
110
|
+
for (const h of recipientHeaders) {
|
|
111
|
+
const headerSize = this.recipientIdSize +
|
|
112
|
+
this.constants.KEY_SIZE_BYTES + h.keySize;
|
|
113
|
+
if (recipientHeadersSize + headerSize < recipientHeadersSize) {
|
|
114
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_RecipientHeadersSizeOverflow));
|
|
115
|
+
}
|
|
116
|
+
recipientHeadersSize += headerSize;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Calculate encrypted size (Data + Tag)
|
|
120
|
+
// AES-GCM tag is 16 bytes
|
|
121
|
+
const encryptedSize = dataToEncrypt.length + 16;
|
|
122
|
+
|
|
123
|
+
const totalSize = this.constants.HEADER_SIZE +
|
|
124
|
+
recipientHeadersSize +
|
|
125
|
+
Constants.ECIES.IV_SIZE + // IV
|
|
126
|
+
encryptedSize;
|
|
127
|
+
|
|
128
|
+
// Check for integer overflow (max safe: 2^31 - 1 for Uint8Array)
|
|
129
|
+
if (totalSize > 0x7FFFFFFF || totalSize < 0) {
|
|
130
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkSizeOverflow));
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Build chunk buffer
|
|
134
|
+
const chunk = new Uint8Array(totalSize);
|
|
135
|
+
const view = new DataView(chunk.buffer);
|
|
136
|
+
let offset = 0;
|
|
137
|
+
|
|
138
|
+
// Write header
|
|
139
|
+
view.setUint32(offset, this.constants.MAGIC, false);
|
|
140
|
+
offset += 4;
|
|
141
|
+
view.setUint16(offset, this.constants.VERSION, false);
|
|
142
|
+
offset += 2;
|
|
143
|
+
view.setUint16(offset, recipients.length, false);
|
|
144
|
+
offset += 2;
|
|
145
|
+
view.setUint32(offset, chunkIndex, false);
|
|
146
|
+
offset += 4;
|
|
147
|
+
view.setUint32(offset, dataToEncrypt.length, false); // Original Size (includes signature if present)
|
|
148
|
+
offset += 4;
|
|
149
|
+
view.setUint32(offset, encryptedSize, false);
|
|
150
|
+
offset += 4;
|
|
151
|
+
view.setUint8(offset, isLast ? this.constants.FLAG_IS_LAST : 0);
|
|
152
|
+
offset += 1;
|
|
153
|
+
|
|
154
|
+
// Write Ephemeral Public Key (33 bytes)
|
|
155
|
+
chunk.set(ephemeralKeyPair.publicKey, offset);
|
|
156
|
+
offset += 33;
|
|
157
|
+
|
|
158
|
+
// Padding to HEADER_SIZE (64 bytes)
|
|
159
|
+
offset = this.constants.HEADER_SIZE;
|
|
160
|
+
|
|
161
|
+
// Write recipient headers
|
|
162
|
+
for (const header of recipientHeaders) {
|
|
163
|
+
chunk.set(header.id, offset);
|
|
164
|
+
offset += this.recipientIdSize;
|
|
165
|
+
view.setUint16(offset, header.keySize, false);
|
|
166
|
+
offset += this.constants.KEY_SIZE_BYTES;
|
|
167
|
+
chunk.set(header.encryptedKey, offset);
|
|
168
|
+
offset += header.keySize;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// Extract the full header (including recipient headers) to use as AAD
|
|
172
|
+
const headerBytes = chunk.slice(0, offset);
|
|
173
|
+
|
|
174
|
+
// Encrypt data with AES-256-GCM using Header as AAD
|
|
175
|
+
const encryptResult = await AESGCMService.encrypt(
|
|
176
|
+
dataToEncrypt,
|
|
177
|
+
symmetricKey,
|
|
178
|
+
true, // Return tag separately
|
|
179
|
+
Constants.ECIES,
|
|
180
|
+
headerBytes // AAD
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// Write IV
|
|
184
|
+
chunk.set(encryptResult.iv, offset);
|
|
185
|
+
offset += Constants.ECIES.IV_SIZE;
|
|
186
|
+
|
|
187
|
+
// Write encrypted data
|
|
188
|
+
chunk.set(encryptResult.encrypted, offset);
|
|
189
|
+
offset += encryptResult.encrypted.length;
|
|
190
|
+
|
|
191
|
+
// Write auth tag
|
|
192
|
+
if (encryptResult.tag) {
|
|
193
|
+
chunk.set(encryptResult.tag, offset);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
index: chunkIndex,
|
|
198
|
+
data: chunk,
|
|
199
|
+
isLast,
|
|
200
|
+
recipientCount: recipients.length,
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Decrypt chunk for specific recipient
|
|
206
|
+
*/
|
|
207
|
+
async decryptChunk(
|
|
208
|
+
chunkData: Uint8Array,
|
|
209
|
+
recipientId: Uint8Array,
|
|
210
|
+
privateKey: Uint8Array,
|
|
211
|
+
senderPublicKey?: Uint8Array,
|
|
212
|
+
): Promise<{ data: Uint8Array; header: IMultiRecipientChunkHeader }> {
|
|
213
|
+
const engine = getEciesI18nEngine();
|
|
214
|
+
if (chunkData.length < this.constants.HEADER_SIZE) {
|
|
215
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkTooSmall));
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
const view = new DataView(chunkData.buffer, chunkData.byteOffset);
|
|
219
|
+
let offset = 0;
|
|
220
|
+
|
|
221
|
+
// Parse header
|
|
222
|
+
const magic = view.getUint32(offset, false);
|
|
223
|
+
offset += 4;
|
|
224
|
+
if (magic !== this.constants.MAGIC) {
|
|
225
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_InvalidChunkMagic));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
const version = view.getUint16(offset, false);
|
|
229
|
+
offset += 2;
|
|
230
|
+
if (version !== this.constants.VERSION) {
|
|
231
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_UnsupportedVersionTemplate, { version }));
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
const recipientCount = view.getUint16(offset, false);
|
|
235
|
+
offset += 2;
|
|
236
|
+
if (recipientCount === 0 || recipientCount > this.constants.MAX_RECIPIENTS) {
|
|
237
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_InvalidRecipientCountTemplate, { count: recipientCount }));
|
|
238
|
+
}
|
|
239
|
+
const chunkIndex = view.getUint32(offset, false);
|
|
240
|
+
offset += 4;
|
|
241
|
+
const originalSize = view.getUint32(offset, false);
|
|
242
|
+
offset += 4;
|
|
243
|
+
const encryptedSize = view.getUint32(offset, false);
|
|
244
|
+
offset += 4;
|
|
245
|
+
const flags = view.getUint8(offset);
|
|
246
|
+
offset += 1;
|
|
247
|
+
|
|
248
|
+
// Read Ephemeral Public Key (33 bytes)
|
|
249
|
+
const ephemeralPublicKey = chunkData.slice(offset, offset + 33);
|
|
250
|
+
offset += 33;
|
|
251
|
+
|
|
252
|
+
offset = this.constants.HEADER_SIZE;
|
|
253
|
+
|
|
254
|
+
// Validate encryptedSize against chunk size
|
|
255
|
+
// We know it must be at least HEADER + IV + EncryptedSize (which includes tag)
|
|
256
|
+
const minChunkSize = this.constants.HEADER_SIZE + Constants.ECIES.IV_SIZE + encryptedSize;
|
|
257
|
+
if (chunkData.length < minChunkSize) {
|
|
258
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkTooSmallForEncryptedSize));
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Find recipient header and decrypt symmetric key
|
|
262
|
+
let symmetricKey: Uint8Array | null = null;
|
|
263
|
+
let tempOffset = offset;
|
|
264
|
+
|
|
265
|
+
for (let i = 0; i < recipientCount; i++) {
|
|
266
|
+
// Check if we have enough data for recipient ID
|
|
267
|
+
if (tempOffset + this.recipientIdSize > chunkData.length) {
|
|
268
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkTruncatedRecipientId));
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
const id = chunkData.slice(tempOffset, tempOffset + this.recipientIdSize);
|
|
272
|
+
tempOffset += this.recipientIdSize;
|
|
273
|
+
|
|
274
|
+
// Check if we have enough data for keySize field
|
|
275
|
+
if (tempOffset + this.constants.KEY_SIZE_BYTES > chunkData.length) {
|
|
276
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkTruncatedKeySize));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
const keySize = view.getUint16(tempOffset, false);
|
|
280
|
+
tempOffset += this.constants.KEY_SIZE_BYTES;
|
|
281
|
+
|
|
282
|
+
// Validate keySize (typical ECIES: 100-400 bytes)
|
|
283
|
+
if (keySize === 0 || keySize > 1000) {
|
|
284
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_InvalidKeySizeTemplate, { size: keySize }));
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Check if we have enough data for the encrypted key
|
|
288
|
+
if (tempOffset + keySize > chunkData.length) {
|
|
289
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkTruncatedEncryptedKey));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const encryptedKey = chunkData.slice(tempOffset, tempOffset + keySize);
|
|
293
|
+
tempOffset += keySize;
|
|
294
|
+
|
|
295
|
+
// Check if this is our recipient
|
|
296
|
+
if (this.arraysEqual(id, recipientId)) {
|
|
297
|
+
// Use Recipient ID as AAD for key decryption
|
|
298
|
+
symmetricKey = await this.ecies.decryptKey(privateKey, encryptedKey, ephemeralPublicKey, id);
|
|
299
|
+
// Don't break - need to skip all recipient headers
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
if (!symmetricKey) {
|
|
304
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_RecipientNotFoundInChunk));
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Update offset to after all recipient headers
|
|
308
|
+
offset = tempOffset;
|
|
309
|
+
|
|
310
|
+
// Extract header bytes for AAD
|
|
311
|
+
const headerBytes = chunkData.slice(0, offset);
|
|
312
|
+
|
|
313
|
+
// Read IV
|
|
314
|
+
if (offset + Constants.ECIES.IV_SIZE > chunkData.length) {
|
|
315
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkTooSmall));
|
|
316
|
+
}
|
|
317
|
+
const iv = chunkData.slice(offset, offset + Constants.ECIES.IV_SIZE);
|
|
318
|
+
offset += Constants.ECIES.IV_SIZE;
|
|
319
|
+
|
|
320
|
+
// Read encrypted data (includes auth tag)
|
|
321
|
+
if (offset + encryptedSize > chunkData.length) {
|
|
322
|
+
throw new Error(engine.translate(EciesComponentId, EciesStringKey.Error_MultiRecipient_ChunkTooSmall));
|
|
323
|
+
}
|
|
324
|
+
const encryptedWithTag = chunkData.slice(offset, offset + encryptedSize);
|
|
325
|
+
offset += encryptedSize;
|
|
326
|
+
|
|
327
|
+
// Decrypt with AAD
|
|
328
|
+
const decrypted = await AESGCMService.decrypt(
|
|
329
|
+
iv,
|
|
330
|
+
encryptedWithTag,
|
|
331
|
+
symmetricKey,
|
|
332
|
+
true,
|
|
333
|
+
Constants.ECIES,
|
|
334
|
+
headerBytes
|
|
335
|
+
);
|
|
336
|
+
|
|
337
|
+
// Verify signature if sender public key provided
|
|
338
|
+
let finalData = decrypted;
|
|
339
|
+
if (senderPublicKey) {
|
|
340
|
+
if (decrypted.length < 64) {
|
|
341
|
+
throw new Error('Decrypted chunk too short to contain signature');
|
|
342
|
+
}
|
|
343
|
+
const signature = decrypted.slice(0, 64);
|
|
344
|
+
const message = decrypted.slice(64);
|
|
345
|
+
|
|
346
|
+
const isValid = this.ecies.core.verify(senderPublicKey, message, signature);
|
|
347
|
+
if (!isValid) {
|
|
348
|
+
throw new Error('Invalid sender signature in chunk');
|
|
349
|
+
}
|
|
350
|
+
finalData = message;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
return {
|
|
354
|
+
data: finalData,
|
|
355
|
+
header: {
|
|
356
|
+
magic,
|
|
357
|
+
version,
|
|
358
|
+
recipientCount,
|
|
359
|
+
chunkIndex,
|
|
360
|
+
originalSize,
|
|
361
|
+
encryptedSize,
|
|
362
|
+
flags,
|
|
363
|
+
},
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
private arraysEqual(a: Uint8Array, b: Uint8Array): boolean {
|
|
368
|
+
if (a.length !== b.length) return false;
|
|
369
|
+
|
|
370
|
+
// Constant-time comparison to prevent timing attacks
|
|
371
|
+
let diff = 0;
|
|
372
|
+
for (let i = 0; i < a.length; i++) {
|
|
373
|
+
diff |= a[i] ^ b[i];
|
|
374
|
+
}
|
|
375
|
+
return diff === 0;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import { Wallet } from '@ethereumjs/wallet';
|
|
2
|
+
import { EciesEncryptionTypeEnum } from '../enumerations/ecies-encryption-type';
|
|
3
|
+
import { Pbkdf2ProfileEnum } from '../enumerations/pbkdf2-profile';
|
|
4
|
+
import { SecureString } from '../secure-string';
|
|
5
|
+
import { hexToUint8Array, uint8ArrayToHex } from '../utils';
|
|
6
|
+
import { AESGCMService } from './aes-gcm';
|
|
7
|
+
import { ECIESService } from './ecies/service';
|
|
8
|
+
import { Pbkdf2Service } from './pbkdf2';
|
|
9
|
+
import { EciesStringKey, PasswordLoginErrorTypeEnum } from '../enumerations';
|
|
10
|
+
import { buildReasonMap, TranslatableGenericError, TypedHandleableError } from '@digitaldefiance/i18n-lib';
|
|
11
|
+
import { IECIESConstants } from '../interfaces/ecies-consts';
|
|
12
|
+
import { Constants } from '../constants';
|
|
13
|
+
import { EciesComponentId } from '../i18n-setup';
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
export class PasswordLoginService {
|
|
17
|
+
protected readonly eciesService: ECIESService;
|
|
18
|
+
protected readonly pbkdf2Service: Pbkdf2Service;
|
|
19
|
+
protected readonly eciesConsts: IECIESConstants;
|
|
20
|
+
public static readonly privateKeyStorageKey = 'encryptedPrivateKey';
|
|
21
|
+
public static readonly saltStorageKey = 'passwordLoginSalt';
|
|
22
|
+
public static readonly encryptedMnemonicStorageKey = 'encryptedMnemonic';
|
|
23
|
+
public static readonly profileStorageKey = 'pbkdf2Profile';
|
|
24
|
+
|
|
25
|
+
constructor(eciesService: ECIESService, pbkdf2Service: Pbkdf2Service, eciesParams: IECIESConstants = Constants.ECIES) {
|
|
26
|
+
this.eciesService = eciesService;
|
|
27
|
+
this.pbkdf2Service = pbkdf2Service;
|
|
28
|
+
this.eciesConsts = eciesParams;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public async createPasswordLoginBundle(
|
|
32
|
+
mnemonic: SecureString,
|
|
33
|
+
password: SecureString,
|
|
34
|
+
profile: Pbkdf2ProfileEnum = Pbkdf2ProfileEnum.BROWSER_PASSWORD,
|
|
35
|
+
): Promise<{
|
|
36
|
+
salt: Uint8Array;
|
|
37
|
+
encryptedPrivateKey: Uint8Array;
|
|
38
|
+
encryptedMnemonic: Uint8Array;
|
|
39
|
+
wallet: Wallet;
|
|
40
|
+
}> {
|
|
41
|
+
const { wallet } = this.eciesService.walletAndSeedFromMnemonic(mnemonic);
|
|
42
|
+
|
|
43
|
+
const derivedKey =
|
|
44
|
+
await this.pbkdf2Service.deriveKeyFromPasswordWithProfileAsync(
|
|
45
|
+
password.valueAsUint8Array,
|
|
46
|
+
profile,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Encrypt private key with derived key
|
|
50
|
+
const privateKeyBytes = wallet.getPrivateKey();
|
|
51
|
+
const { encrypted, iv, tag } = await AESGCMService.encrypt(
|
|
52
|
+
privateKeyBytes,
|
|
53
|
+
derivedKey.hash,
|
|
54
|
+
true,
|
|
55
|
+
);
|
|
56
|
+
if (!tag) {
|
|
57
|
+
throw new TranslatableGenericError(EciesComponentId, EciesStringKey.Error_Utils_EncryptionFailedNoAuthTag);
|
|
58
|
+
}
|
|
59
|
+
const encryptedPrivateKey = AESGCMService.combineIvTagAndEncryptedData(
|
|
60
|
+
iv,
|
|
61
|
+
encrypted,
|
|
62
|
+
tag,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// now use the public key to encrypt the mnemonic and store it
|
|
66
|
+
const encryptedMnemonic = await this.eciesService.encrypt(
|
|
67
|
+
EciesEncryptionTypeEnum.Simple,
|
|
68
|
+
wallet.getPublicKey(),
|
|
69
|
+
mnemonic.valueAsUint8Array,
|
|
70
|
+
);
|
|
71
|
+
|
|
72
|
+
return {
|
|
73
|
+
salt: derivedKey.salt,
|
|
74
|
+
encryptedPrivateKey: encryptedPrivateKey,
|
|
75
|
+
encryptedMnemonic: encryptedMnemonic,
|
|
76
|
+
wallet,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Set up password login by deriving a key from the password and using it to encrypt
|
|
82
|
+
* @param mnemonic The user's mnemonic
|
|
83
|
+
* @param password The user's password
|
|
84
|
+
*/
|
|
85
|
+
public async setupPasswordLoginLocalStorageBundle(
|
|
86
|
+
mnemonic: SecureString,
|
|
87
|
+
password: SecureString,
|
|
88
|
+
profile: Pbkdf2ProfileEnum = Pbkdf2ProfileEnum.BROWSER_PASSWORD,
|
|
89
|
+
): Promise<Wallet> {
|
|
90
|
+
const { salt, encryptedPrivateKey, encryptedMnemonic, wallet } =
|
|
91
|
+
await this.createPasswordLoginBundle(mnemonic, password, profile);
|
|
92
|
+
|
|
93
|
+
// store the salt and encrypted private key in local storage
|
|
94
|
+
try {
|
|
95
|
+
localStorage.setItem(
|
|
96
|
+
PasswordLoginService.saltStorageKey,
|
|
97
|
+
uint8ArrayToHex(salt),
|
|
98
|
+
);
|
|
99
|
+
localStorage.setItem(
|
|
100
|
+
PasswordLoginService.privateKeyStorageKey,
|
|
101
|
+
uint8ArrayToHex(encryptedPrivateKey),
|
|
102
|
+
);
|
|
103
|
+
localStorage.setItem(
|
|
104
|
+
PasswordLoginService.encryptedMnemonicStorageKey,
|
|
105
|
+
uint8ArrayToHex(encryptedMnemonic),
|
|
106
|
+
);
|
|
107
|
+
localStorage.setItem(
|
|
108
|
+
PasswordLoginService.profileStorageKey,
|
|
109
|
+
profile,
|
|
110
|
+
);
|
|
111
|
+
} catch (error) {
|
|
112
|
+
throw new TypedHandleableError<typeof PasswordLoginErrorTypeEnum, EciesStringKey>(EciesComponentId, PasswordLoginErrorTypeEnum.FailedToStoreLoginData, buildReasonMap<typeof PasswordLoginErrorTypeEnum, EciesStringKey>(PasswordLoginErrorTypeEnum, ['Error', 'PasswordLoginError']), new Error(), { cause: error instanceof Error ? error : undefined });
|
|
113
|
+
}
|
|
114
|
+
return wallet;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public async getWalletAndMnemonicFromEncryptedPasswordBundle(
|
|
118
|
+
salt: Uint8Array,
|
|
119
|
+
encryptedPrivateKey: Uint8Array,
|
|
120
|
+
encryptedMnemonic: Uint8Array,
|
|
121
|
+
password: SecureString,
|
|
122
|
+
profile: Pbkdf2ProfileEnum = Pbkdf2ProfileEnum.BROWSER_PASSWORD,
|
|
123
|
+
): Promise<{ wallet: Wallet; mnemonic: SecureString }> {
|
|
124
|
+
if (!salt || !encryptedPrivateKey || !encryptedMnemonic) {
|
|
125
|
+
throw new TypedHandleableError<typeof PasswordLoginErrorTypeEnum, EciesStringKey>(EciesComponentId, PasswordLoginErrorTypeEnum.PasswordLoginNotSetUp, buildReasonMap<typeof PasswordLoginErrorTypeEnum, EciesStringKey>(PasswordLoginErrorTypeEnum, ['Error', 'PasswordLoginError']), new Error());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const derivedKey =
|
|
129
|
+
await this.pbkdf2Service.deriveKeyFromPasswordWithProfileAsync(
|
|
130
|
+
password.valueAsUint8Array,
|
|
131
|
+
profile,
|
|
132
|
+
salt,
|
|
133
|
+
);
|
|
134
|
+
|
|
135
|
+
// Decrypt private key with derived key
|
|
136
|
+
const { iv, encryptedDataWithTag } = AESGCMService.splitEncryptedData(
|
|
137
|
+
encryptedPrivateKey,
|
|
138
|
+
true,
|
|
139
|
+
this.eciesConsts,
|
|
140
|
+
);
|
|
141
|
+
const privateKeyBytes = await AESGCMService.decrypt(
|
|
142
|
+
iv,
|
|
143
|
+
encryptedDataWithTag,
|
|
144
|
+
derivedKey.hash,
|
|
145
|
+
true,
|
|
146
|
+
this.eciesConsts,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
const wallet = Wallet.fromPrivateKey(privateKeyBytes);
|
|
150
|
+
|
|
151
|
+
// now decrypt the mnemonic
|
|
152
|
+
const decryptedMnemonic =
|
|
153
|
+
await this.eciesService.decryptSimpleOrSingleWithHeader(
|
|
154
|
+
true,
|
|
155
|
+
wallet.getPrivateKey(),
|
|
156
|
+
encryptedMnemonic,
|
|
157
|
+
);
|
|
158
|
+
|
|
159
|
+
return { wallet, mnemonic: new SecureString(decryptedMnemonic) };
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Recover wallet and mnemonic from password
|
|
164
|
+
* @param password The user's password
|
|
165
|
+
* @returns The user's wallet and mnemonic
|
|
166
|
+
*/
|
|
167
|
+
public async getWalletAndMnemonicFromLocalStorageBundle(
|
|
168
|
+
password: SecureString,
|
|
169
|
+
): Promise<{ wallet: Wallet; mnemonic: SecureString }> {
|
|
170
|
+
const saltHex = localStorage.getItem(PasswordLoginService.saltStorageKey);
|
|
171
|
+
const encryptedPrivateKeyHex = localStorage.getItem(
|
|
172
|
+
PasswordLoginService.privateKeyStorageKey,
|
|
173
|
+
);
|
|
174
|
+
const encryptedMnemonicHex = localStorage.getItem(
|
|
175
|
+
PasswordLoginService.encryptedMnemonicStorageKey,
|
|
176
|
+
);
|
|
177
|
+
const profileStr = localStorage.getItem(PasswordLoginService.profileStorageKey);
|
|
178
|
+
|
|
179
|
+
if (
|
|
180
|
+
!saltHex ||
|
|
181
|
+
!encryptedPrivateKeyHex ||
|
|
182
|
+
!encryptedMnemonicHex ||
|
|
183
|
+
saltHex === '' ||
|
|
184
|
+
encryptedPrivateKeyHex === '' ||
|
|
185
|
+
encryptedMnemonicHex === ''
|
|
186
|
+
) {
|
|
187
|
+
throw new TypedHandleableError<typeof PasswordLoginErrorTypeEnum, EciesStringKey>(EciesComponentId, PasswordLoginErrorTypeEnum.PasswordLoginNotSetUp, buildReasonMap<typeof PasswordLoginErrorTypeEnum, EciesStringKey>(PasswordLoginErrorTypeEnum, ['Error', 'PasswordLoginError']), new Error());
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const salt = hexToUint8Array(saltHex);
|
|
191
|
+
const encryptedPrivateKey = hexToUint8Array(encryptedPrivateKeyHex);
|
|
192
|
+
const encryptedMnemonic = hexToUint8Array(encryptedMnemonicHex);
|
|
193
|
+
const profile = (profileStr as Pbkdf2ProfileEnum) || Pbkdf2ProfileEnum.BROWSER_PASSWORD;
|
|
194
|
+
|
|
195
|
+
return await this.getWalletAndMnemonicFromEncryptedPasswordBundle(
|
|
196
|
+
salt,
|
|
197
|
+
encryptedPrivateKey,
|
|
198
|
+
encryptedMnemonic,
|
|
199
|
+
password,
|
|
200
|
+
profile,
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
*
|
|
206
|
+
* @returns True if password login is set up (i.e. salt and encrypted private key are in local storage)
|
|
207
|
+
*/
|
|
208
|
+
public static isPasswordLoginSetup(): boolean {
|
|
209
|
+
const saltHex = localStorage.getItem(PasswordLoginService.saltStorageKey);
|
|
210
|
+
const encryptedPrivateKeyHex = localStorage.getItem(
|
|
211
|
+
PasswordLoginService.privateKeyStorageKey,
|
|
212
|
+
);
|
|
213
|
+
const encryptedMnemonicHex = localStorage.getItem(
|
|
214
|
+
PasswordLoginService.encryptedMnemonicStorageKey,
|
|
215
|
+
);
|
|
216
|
+
|
|
217
|
+
return !!(
|
|
218
|
+
saltHex &&
|
|
219
|
+
encryptedPrivateKeyHex &&
|
|
220
|
+
encryptedMnemonicHex &&
|
|
221
|
+
saltHex !== '' &&
|
|
222
|
+
encryptedPrivateKeyHex !== '' &&
|
|
223
|
+
encryptedMnemonicHex !== ''
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
}
|