@brightchain/brightchain-lib 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/brightchain-lib/README.md +39 -1
  2. package/package.json +2 -2
  3. package/src/index.d.ts +1 -1
  4. package/src/index.d.ts.map +1 -1
  5. package/src/index.js +2 -3
  6. package/src/index.js.map +1 -1
  7. package/src/lib/access/ecies.d.ts.map +1 -1
  8. package/src/lib/access/ecies.js +3 -3
  9. package/src/lib/access/ecies.js.map +1 -1
  10. package/src/lib/blocks/encrypted.d.ts +87 -9
  11. package/src/lib/blocks/encrypted.d.ts.map +1 -1
  12. package/src/lib/blocks/encrypted.js +130 -50
  13. package/src/lib/blocks/encrypted.js.map +1 -1
  14. package/src/lib/blocks/encryptedBlockFactory.d.ts.map +1 -1
  15. package/src/lib/blocks/encryptedBlockFactory.js +13 -13
  16. package/src/lib/blocks/encryptedBlockFactory.js.map +1 -1
  17. package/src/lib/blocks/ephemeral.d.ts.map +1 -1
  18. package/src/lib/blocks/ephemeral.js +3 -3
  19. package/src/lib/blocks/ephemeral.js.map +1 -1
  20. package/src/lib/brightChain.js +2 -2
  21. package/src/lib/brightChain.js.map +1 -1
  22. package/src/lib/browserBrightChain.js +2 -2
  23. package/src/lib/browserBrightChain.js.map +1 -1
  24. package/src/lib/browserConfig.d.ts +30 -2
  25. package/src/lib/browserConfig.d.ts.map +1 -1
  26. package/src/lib/browserConfig.js +45 -7
  27. package/src/lib/browserConfig.js.map +1 -1
  28. package/src/lib/constants.d.ts +6 -200
  29. package/src/lib/constants.d.ts.map +1 -1
  30. package/src/lib/constants.js +7 -138
  31. package/src/lib/constants.js.map +1 -1
  32. package/src/lib/documents/network/networkDocument.d.ts +4 -4
  33. package/src/lib/documents/network/networkDocument.d.ts.map +1 -1
  34. package/src/lib/ecies-config.d.ts +1 -1
  35. package/src/lib/ecies-config.d.ts.map +1 -1
  36. package/src/lib/ecies-config.js +8 -8
  37. package/src/lib/ecies-config.js.map +1 -1
  38. package/src/lib/encryptedBlockMetadata.d.ts.map +1 -1
  39. package/src/lib/encryptedBlockMetadata.js +2 -2
  40. package/src/lib/encryptedBlockMetadata.js.map +1 -1
  41. package/src/lib/index.d.ts +0 -2
  42. package/src/lib/index.d.ts.map +1 -1
  43. package/src/lib/index.js +0 -2
  44. package/src/lib/index.js.map +1 -1
  45. package/src/lib/interfaces/clusterKeys.d.ts +2 -2
  46. package/src/lib/interfaces/clusterKeys.d.ts.map +1 -1
  47. package/src/lib/interfaces/constants.d.ts +2 -60
  48. package/src/lib/interfaces/constants.d.ts.map +1 -1
  49. package/src/lib/interfaces/member/operational.d.ts +3 -3
  50. package/src/lib/interfaces/member/operational.d.ts.map +1 -1
  51. package/src/lib/interfaces/messaging/messageSystemConfig.d.ts +3 -0
  52. package/src/lib/interfaces/messaging/messageSystemConfig.d.ts.map +1 -1
  53. package/src/lib/interfaces/messaging/messageSystemConfig.js +14 -0
  54. package/src/lib/interfaces/messaging/messageSystemConfig.js.map +1 -1
  55. package/src/lib/interfaces/network/node.d.ts +5 -5
  56. package/src/lib/interfaces/network/node.d.ts.map +1 -1
  57. package/src/lib/interfaces/storage/blockStore.d.ts +6 -0
  58. package/src/lib/interfaces/storage/blockStore.d.ts.map +1 -1
  59. package/src/lib/schemas/network/networkDocumentSchema.js +1 -1
  60. package/src/lib/schemas/network/networkDocumentSchema.js.map +1 -1
  61. package/src/lib/services/blockCapacity.service.d.ts.map +1 -1
  62. package/src/lib/services/blockCapacity.service.js +17 -15
  63. package/src/lib/services/blockCapacity.service.js.map +1 -1
  64. package/src/lib/services/blockService.d.ts.map +1 -1
  65. package/src/lib/services/blockService.js +10 -7
  66. package/src/lib/services/blockService.js.map +1 -1
  67. package/src/lib/services/cblService.d.ts.map +1 -1
  68. package/src/lib/services/cblService.js +12 -12
  69. package/src/lib/services/cblService.js.map +1 -1
  70. package/src/lib/services/checksum.service.d.ts.map +1 -1
  71. package/src/lib/services/checksum.service.js +2 -2
  72. package/src/lib/services/checksum.service.js.map +1 -1
  73. package/src/lib/services/fec.service.js +6 -6
  74. package/src/lib/services/fec.service.js.map +1 -1
  75. package/src/lib/services/index.d.ts +1 -0
  76. package/src/lib/services/index.d.ts.map +1 -1
  77. package/src/lib/services/index.js +1 -0
  78. package/src/lib/services/index.js.map +1 -1
  79. package/src/lib/services/messaging/messageCBLService.d.ts +1 -0
  80. package/src/lib/services/messaging/messageCBLService.d.ts.map +1 -1
  81. package/src/lib/services/messaging/messageCBLService.js +15 -14
  82. package/src/lib/services/messaging/messageCBLService.js.map +1 -1
  83. package/src/lib/services/sealing.service.d.ts.map +1 -1
  84. package/src/lib/services/sealing.service.js +3 -4
  85. package/src/lib/services/sealing.service.js.map +1 -1
  86. package/src/lib/services/tupleStorageService.d.ts +75 -0
  87. package/src/lib/services/tupleStorageService.d.ts.map +1 -0
  88. package/src/lib/services/tupleStorageService.js +194 -0
  89. package/src/lib/services/tupleStorageService.js.map +1 -0
  90. package/src/lib/simpleBrightChain.d.ts.map +1 -1
  91. package/src/lib/simpleBrightChain.js +1 -2
  92. package/src/lib/simpleBrightChain.js.map +1 -1
  93. package/src/lib/types/checksum.d.ts.map +1 -1
  94. package/src/lib/types/checksum.js +6 -7
  95. package/src/lib/types/checksum.js.map +1 -1
  96. package/src/lib/utils/validator.js +2 -2
  97. package/src/lib/utils/validator.js.map +1 -1
  98. package/src/lib/brightChainConsts.d.ts +0 -51
  99. package/src/lib/brightChainConsts.d.ts.map +0 -1
  100. package/src/lib/brightChainConsts.js +0 -26
  101. package/src/lib/brightChainConsts.js.map +0 -1
  102. package/src/lib/pbkdf2Profiles.d.ts +0 -6
  103. package/src/lib/pbkdf2Profiles.d.ts.map +0 -1
  104. package/src/lib/pbkdf2Profiles.js +0 -3
  105. package/src/lib/pbkdf2Profiles.js.map +0 -1
@@ -13,9 +13,11 @@
13
13
  - **Brokered Anonymity**: Forward Error Correction with quorum-based identity recovery
14
14
 
15
15
  ### 📦 Owner-Free File System (OFFS)
16
+ - **TUPLE Storage**: All data stored as 3-block TUPLEs (data + 2 randomizers) for complete plausible deniability
16
17
  - **Block-based Storage**: Files broken into encrypted blocks with XOR randomization
17
18
  - **Deduplication**: SHA-512 based block identification prevents duplicate storage
18
19
  - **Distributed Architecture**: Decentralized storage with no single point of failure
20
+ - **Legal Protection**: True owner-free storage ensures no single party can be compelled to produce meaningful data
19
21
 
20
22
  ### ⚡ Energy-Efficient Design
21
23
  - **Joule Currency**: All operations measured in actual energy consumption
@@ -255,7 +257,43 @@ If you're upgrading from BrightChain v1.x, see our comprehensive [Migration Guid
255
257
 
256
258
  See [MIGRATION.md](./MIGRATION.md) for complete details.
257
259
 
258
- ### Working with Encrypted Blocks
260
+ ### TUPLE Storage
261
+
262
+ BrightChain v2.1+ implements complete Owner-Free Filesystem compliance through TUPLE storage:
263
+
264
+ ```typescript
265
+ import { TupleStorageService, BlockSize } from '@brightchain/brightchain-lib';
266
+
267
+ // Initialize TUPLE storage service
268
+ const blockStore = ...; // Your block store instance
269
+ const tupleService = new TupleStorageService(blockStore);
270
+
271
+ // Store data as a TUPLE (3 blocks: data ⊕ R1 ⊕ R2, R1, R2)
272
+ const data = new TextEncoder().encode("Sensitive information");
273
+ const result = await tupleService.storeTuple(data, {
274
+ durabilityLevel: DurabilityLevel.High,
275
+ expiresAt: new Date(Date.now() + 86400000), // 24 hours
276
+ });
277
+
278
+ console.log('TUPLE Magnet URL:', result.magnetUrl);
279
+ // magnet:?xt=urn:brightchain:tuple&bs=1024&d=abc...&r1=def...&r2=ghi...
280
+
281
+ // Retrieve original data from TUPLE
282
+ const components = tupleService.parseTupleMagnetUrl(result.magnetUrl);
283
+ const originalData = await tupleService.retrieveTuple(
284
+ components.dataBlockId,
285
+ components.randomizerBlockIds,
286
+ components.parityBlockIds,
287
+ );
288
+ ```
289
+
290
+ **Why TUPLEs?**
291
+ - **Plausible Deniability**: No single block contains identifiable data
292
+ - **Legal Protection**: Node operators cannot be compelled to produce meaningful data
293
+ - **Complete OFF Compliance**: All data stored as 3 blocks (not just 2)
294
+ - **Brokered Anonymity**: Supports quorum-based identity recovery
295
+
296
+ See [TUPLE Storage Architecture](../../docs/TUPLE_Storage_Architecture.md) for complete details.
259
297
 
260
298
  ```typescript
261
299
  import {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brightchain/brightchain-lib",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "BrightChain core library - browser-compatible blockchain storage",
5
5
  "main": "src/index.js",
6
6
  "types": "src/index.d.ts",
@@ -37,7 +37,7 @@
37
37
  "author": "Digital Defiance",
38
38
  "license": "MIT",
39
39
  "dependencies": {
40
- "@digitaldefiance/ecies-lib": "^4.12.8",
40
+ "@digitaldefiance/ecies-lib": "^4.13.1",
41
41
  "@digitaldefiance/i18n-lib": "^3.8.16",
42
42
  "tslib": "^2.3.0"
43
43
  },
package/src/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
1
  export * from './lib';
2
- export { CBL, default as CONSTANTS, FEC, JWT, SEALING, SITE, TUPLE, } from './lib/constants';
2
+ export { BC_FEC, CBL, default as CONSTANTS, SEALING, SITE, TUPLE, } from './lib/constants';
3
3
  export { EciesConfig } from './lib/ecies-config';
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../brightchain-lib/src/index.ts"],"names":[],"mappings":"AAEA,cAAc,OAAO,CAAC;AAGtB,OAAO,EACL,GAAG,EACH,OAAO,IAAI,SAAS,EACpB,GAAG,EACH,GAAG,EACH,OAAO,EACP,IAAI,EACJ,KAAK,GACN,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../brightchain-lib/src/index.ts"],"names":[],"mappings":"AAEA,cAAc,OAAO,CAAC;AAGtB,OAAO,EACL,MAAM,EACN,GAAG,EACH,OAAO,IAAI,SAAS,EACpB,OAAO,EACP,IAAI,EACJ,KAAK,GACN,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC"}
package/src/index.js CHANGED
@@ -1,16 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EciesConfig = exports.TUPLE = exports.SITE = exports.SEALING = exports.JWT = exports.FEC = exports.CONSTANTS = exports.CBL = void 0;
3
+ exports.EciesConfig = exports.TUPLE = exports.SITE = exports.SEALING = exports.CONSTANTS = exports.CBL = exports.BC_FEC = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  // Full Node.js exports (includes all functionality)
6
6
  // For browser-only exports, use './browser'
7
7
  tslib_1.__exportStar(require("./lib"), exports);
8
8
  // Export constants with named exports for backward compatibility
9
9
  var constants_1 = require("./lib/constants");
10
+ Object.defineProperty(exports, "BC_FEC", { enumerable: true, get: function () { return constants_1.BC_FEC; } });
10
11
  Object.defineProperty(exports, "CBL", { enumerable: true, get: function () { return constants_1.CBL; } });
11
12
  Object.defineProperty(exports, "CONSTANTS", { enumerable: true, get: function () { return constants_1.default; } });
12
- Object.defineProperty(exports, "FEC", { enumerable: true, get: function () { return constants_1.FEC; } });
13
- Object.defineProperty(exports, "JWT", { enumerable: true, get: function () { return constants_1.JWT; } });
14
13
  Object.defineProperty(exports, "SEALING", { enumerable: true, get: function () { return constants_1.SEALING; } });
15
14
  Object.defineProperty(exports, "SITE", { enumerable: true, get: function () { return constants_1.SITE; } });
16
15
  Object.defineProperty(exports, "TUPLE", { enumerable: true, get: function () { return constants_1.TUPLE; } });
package/src/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../brightchain-lib/src/index.ts"],"names":[],"mappings":";;;;AAAA,oDAAoD;AACpD,4CAA4C;AAC5C,gDAAsB;AAEtB,iEAAiE;AACjE,6CAQyB;AAPvB,gGAAA,GAAG,OAAA;AACH,sGAAA,OAAO,OAAa;AACpB,gGAAA,GAAG,OAAA;AACH,gGAAA,GAAG,OAAA;AACH,oGAAA,OAAO,OAAA;AACP,iGAAA,IAAI,OAAA;AACJ,kGAAA,KAAK,OAAA;AAEP,mDAAiD;AAAxC,2GAAA,WAAW,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../brightchain-lib/src/index.ts"],"names":[],"mappings":";;;;AAAA,oDAAoD;AACpD,4CAA4C;AAC5C,gDAAsB;AAEtB,iEAAiE;AACjE,6CAOyB;AANvB,mGAAA,MAAM,OAAA;AACN,gGAAA,GAAG,OAAA;AACH,sGAAA,OAAO,OAAa;AACpB,oGAAA,OAAO,OAAA;AACP,iGAAA,IAAI,OAAA;AACJ,kGAAA,KAAK,OAAA;AAEP,mDAAiD;AAAxC,2GAAA,WAAW,OAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"ecies.d.ts","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/access/ecies.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,qBAAa,UAAU;WACD,OAAO,CACzB,iBAAiB,EAAE,UAAU,EAC7B,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,UAAU,CAAC;WASF,OAAO,CACzB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,UAAU,GACxB,OAAO,CAAC,UAAU,CAAC;WASF,qBAAqB,CACvC,UAAU,EAAE,UAAU,EACtB,kBAAkB,EAAE,UAAU,EAC9B,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC;QACT,SAAS,EAAE,UAAU,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CAWH"}
1
+ {"version":3,"file":"ecies.d.ts","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/access/ecies.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,qBAAa,UAAU;WACD,OAAO,CACzB,iBAAiB,EAAE,UAAU,EAC7B,OAAO,EAAE,UAAU,GAClB,OAAO,CAAC,UAAU,CAAC;WAQF,OAAO,CACzB,UAAU,EAAE,UAAU,EACtB,aAAa,EAAE,UAAU,GACxB,OAAO,CAAC,UAAU,CAAC;WAQF,qBAAqB,CACvC,UAAU,EAAE,UAAU,EACtB,kBAAkB,EAAE,UAAU,EAC9B,EAAE,EAAE,UAAU,EACd,OAAO,EAAE,UAAU,EACnB,SAAS,EAAE,UAAU,GACpB,OAAO,CAAC;QACT,SAAS,EAAE,UAAU,CAAC;QACtB,gBAAgB,CAAC,EAAE,MAAM,CAAC;KAC3B,CAAC;CAWH"}
@@ -9,14 +9,14 @@ const service_provider_1 = require("../services/service.provider");
9
9
  class BlockECIES {
10
10
  static async encrypt(receiverPublicKey, message) {
11
11
  // Use encryptSimpleOrSingle (encryptSimple = true) from new ECIES service
12
- return service_provider_1.ServiceProvider.getInstance().eciesService.encryptSimpleOrSingle(true, receiverPublicKey, message);
12
+ return service_provider_1.ServiceProvider.getInstance().eciesService.encryptBasic(receiverPublicKey, message);
13
13
  }
14
14
  static async decrypt(privateKey, encryptedData) {
15
15
  // Use decryptSimpleOrSingleWithHeader (decryptSimple = false) from new ECIES service
16
- return service_provider_1.ServiceProvider.getInstance().eciesService.decryptSimpleOrSingleWithHeader(false, privateKey, encryptedData);
16
+ return service_provider_1.ServiceProvider.getInstance().eciesService.decryptWithLengthAndHeader(privateKey, encryptedData);
17
17
  }
18
18
  static async decryptWithComponents(privateKey, ephemeralPublicKey, iv, authTag, encrypted) {
19
- const result = service_provider_1.ServiceProvider.getInstance().eciesService.decryptSingleWithComponents(privateKey, ephemeralPublicKey, iv, authTag, encrypted);
19
+ const result = service_provider_1.ServiceProvider.getInstance().eciesService.decryptWithComponents(privateKey, ephemeralPublicKey, iv, authTag, encrypted);
20
20
  return result;
21
21
  }
22
22
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ecies.js","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/access/ecies.ts"],"names":[],"mappings":";;;AAAA,mEAA+D;AAE/D;;;GAGG;AACH,MAAa,UAAU;IACd,MAAM,CAAC,KAAK,CAAC,OAAO,CACzB,iBAA6B,EAC7B,OAAmB;QAEnB,0EAA0E;QAC1E,OAAO,kCAAe,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,qBAAqB,CACrE,IAAI,EACJ,iBAAiB,EACjB,OAAO,CACR,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,OAAO,CACzB,UAAsB,EACtB,aAAyB;QAEzB,qFAAqF;QACrF,OAAO,kCAAe,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,+BAA+B,CAC/E,KAAK,EACL,UAAU,EACV,aAAa,CACd,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,qBAAqB,CACvC,UAAsB,EACtB,kBAA8B,EAC9B,EAAc,EACd,OAAmB,EACnB,SAAqB;QAKrB,MAAM,MAAM,GACV,kCAAe,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,2BAA2B,CACpE,UAAU,EACV,kBAAkB,EAClB,EAAE,EACF,OAAO,EACP,SAAS,CACV,CAAC;QACJ,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA7CD,gCA6CC"}
1
+ {"version":3,"file":"ecies.js","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/access/ecies.ts"],"names":[],"mappings":";;;AAAA,mEAA+D;AAE/D;;;GAGG;AACH,MAAa,UAAU;IACd,MAAM,CAAC,KAAK,CAAC,OAAO,CACzB,iBAA6B,EAC7B,OAAmB;QAEnB,0EAA0E;QAC1E,OAAO,kCAAe,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,YAAY,CAC5D,iBAAiB,EACjB,OAAO,CACR,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,OAAO,CACzB,UAAsB,EACtB,aAAyB;QAEzB,qFAAqF;QACrF,OAAO,kCAAe,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,0BAA0B,CAC1E,UAAU,EACV,aAAa,CACd,CAAC;IACJ,CAAC;IAEM,MAAM,CAAC,KAAK,CAAC,qBAAqB,CACvC,UAAsB,EACtB,kBAA8B,EAC9B,EAAc,EACd,OAAmB,EACnB,SAAqB;QAKrB,MAAM,MAAM,GACV,kCAAe,CAAC,WAAW,EAAE,CAAC,YAAY,CAAC,qBAAqB,CAC9D,UAAU,EACV,kBAAkB,EAClB,EAAE,EACF,OAAO,EACP,SAAS,CACV,CAAC;QACJ,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA3CD,gCA2CC"}
@@ -1,4 +1,4 @@
1
- import { IMultiEncryptedParsedHeader, ISingleEncryptedParsedHeader, Member, type PlatformID } from '@digitaldefiance/ecies-lib';
1
+ import { IMultiEncryptedParsedHeader, ISingleEncryptedParsedHeader, Member, TypedIdProviderWrapper, type PlatformID } from '@digitaldefiance/ecies-lib';
2
2
  import { EncryptedBlockMetadata } from '../encryptedBlockMetadata';
3
3
  import { BlockDataType } from '../enumerations/blockDataType';
4
4
  import { BlockEncryptionType } from '../enumerations/blockEncryptionType';
@@ -6,25 +6,85 @@ import { BlockSize } from '../enumerations/blockSize';
6
6
  import { BlockType } from '../enumerations/blockType';
7
7
  import { IEncryptedBlock } from '../interfaces/blocks/encrypted';
8
8
  import { IEphemeralBlock } from '../interfaces/blocks/ephemeral';
9
+ import { ServiceProvider } from '../services/service.provider';
9
10
  import { Checksum } from '../types/checksum';
10
11
  import { EphemeralBlock } from './ephemeral';
11
12
  /**
12
13
  * Base class for encrypted blocks.
13
14
  * Adds encryption-specific header data and overhead calculations.
14
15
  *
16
+ * BrightChain adopts ecies-lib's versioned encryption format as the canonical standard.
17
+ *
15
18
  * Block Structure:
16
19
  * [Layer 0 Header][Layer 1 Header][...][Encryption Header][Encrypted Payload][Padding]
17
20
  *
18
- * Single Encryption Header:
19
- * [Encryption Type (1 byte)][Recipient GUID (16 bytes)][Ephemeral Public Key (65 bytes)][IV (16 bytes)][Auth Tag (16 bytes)][Data]
21
+ * ═══════════════════════════════════════════════════════════════════════════════════════
22
+ * SINGLE-RECIPIENT ENCRYPTION (WITH_LENGTH format, type 0x42)
23
+ * ═══════════════════════════════════════════════════════════════════════════════════════
24
+ *
25
+ * BrightChain uses WITH_LENGTH format for single-recipient encryption because:
26
+ * 1. The data length field enables streaming decryption
27
+ * 2. It's only 8 bytes more than BASIC
28
+ * 3. Block sizes are known, making length verification valuable
29
+ *
30
+ * Byte Layout:
31
+ * ┌─────────────────────────────────────────────────────────────────────────────────────┐
32
+ * │ [EncType][RecipientID][Version][CipherSuite][Type][PubKey][IV][AuthTag][Len][Data] │
33
+ * │ [1 ][idSize ][1 ][1 ][1 ][33 ][12][16 ][8 ][...] │
34
+ * └─────────────────────────────────────────────────────────────────────────────────────┘
35
+ *
36
+ * | Offset | Size | Field | Description |
37
+ * |-------------|--------|------------------|------------------------------------------|
38
+ * | 0 | 1 | EncryptionType | BlockEncryptionType.SingleRecipient (1) |
39
+ * | 1 | idSize | RecipientID | BrightChain routing ID |
40
+ * | 1+idSize | 1 | Version | Protocol version (0x01) |
41
+ * | 2+idSize | 1 | CipherSuite | AES-256-GCM (0x01) |
42
+ * | 3+idSize | 1 | EncryptionType | WITH_LENGTH (0x42) |
43
+ * | 4+idSize | 33 | EphemeralPubKey | Compressed secp256k1 public key |
44
+ * | 37+idSize | 12 | IV | Initialization vector (NIST SP 800-38D) |
45
+ * | 49+idSize | 16 | AuthTag | GCM authentication tag |
46
+ * | 65+idSize | 8 | DataLength | Original data length (big-endian) |
47
+ * | 73+idSize | ... | EncryptedData | Ciphertext |
48
+ *
49
+ * Total overhead: 1 + idSize + ECIES.WITH_LENGTH.FIXED_OVERHEAD_SIZE = 1 + idSize + 72
50
+ * Default (GUID, idSize=16): 1 + 16 + 72 = 89 bytes
51
+ * ObjectID (idSize=12): 1 + 12 + 72 = 85 bytes
52
+ *
53
+ * ═══════════════════════════════════════════════════════════════════════════════════════
54
+ * MULTI-RECIPIENT ENCRYPTION (MULTIPLE format, type 0x63)
55
+ * ═══════════════════════════════════════════════════════════════════════════════════════
56
+ *
57
+ * Byte Layout:
58
+ * ┌─────────────────────────────────────────────────────────────────────────────────────┐
59
+ * │ [EncType][Ver][CS][PubKey][IV][Tag][Len][Count][RecipientEntries...][EncryptedData] │
60
+ * │ [1 ][1 ][1 ][33 ][12][16 ][8 ][2 ][variable ][...] │
61
+ * └─────────────────────────────────────────────────────────────────────────────────────┘
62
+ *
63
+ * Recipient Entry Layout (per recipient):
64
+ * | Offset | Size | Field | Description |
65
+ * |-------------|--------|---------------|-------------------------------------------|
66
+ * | 0 | idSize | RecipientID | Recipient identifier |
67
+ * | idSize | 12 | KeyIV | IV for this recipient's key encryption |
68
+ * | idSize+12 | 16 | KeyAuthTag | Auth tag for key encryption |
69
+ * | idSize+28 | 32 | EncryptedKey | Encrypted symmetric key |
70
+ *
71
+ * Per-recipient overhead: idSize + ECIES.MULTIPLE.ENCRYPTED_KEY_SIZE = idSize + 60
72
+ *
73
+ * Total overhead formula:
74
+ * 1 + ECIES.MULTIPLE.FIXED_OVERHEAD_SIZE + DATA_LENGTH_SIZE + RECIPIENT_COUNT_SIZE
75
+ * + (recipientCount * (idSize + ENCRYPTED_KEY_SIZE))
76
+ * = 1 + 64 + 8 + 2 + (recipientCount * (idSize + 60))
77
+ * = 75 + (recipientCount * (idSize + 60))
20
78
  *
21
- * Multi Encryption Header:
22
- * [Encryption Type (1 byte)][Data Length (8 bytes)][Recipient count (2 bytes)][Recipient GUIDs (16 bytes * recipientCount)][Recipient keys (129 bytes)][Data]
79
+ * @see design.md for complete format specification
80
+ * @see Requirements 2.2, 2.3, 3.3, 8.4
23
81
  */
24
82
  export declare class EncryptedBlock<TID extends PlatformID = Uint8Array> extends EphemeralBlock<TID> implements IEncryptedBlock<TID> {
25
83
  protected readonly _encryptionType: BlockEncryptionType;
26
84
  protected readonly _recipients: Array<TID>;
27
85
  protected readonly _recipientWithKey: Member<TID>;
86
+ protected readonly _serviceProvider: ServiceProvider<TID>;
87
+ protected readonly _idProvider: TypedIdProviderWrapper<TID>;
28
88
  protected _cachedEncryptionDetails?: ISingleEncryptedParsedHeader | IMultiEncryptedParsedHeader<TID>;
29
89
  /**
30
90
  * Creates an instance of EncryptedBlock.
@@ -67,9 +127,19 @@ export declare class EncryptedBlock<TID extends PlatformID = Uint8Array> extends
67
127
  */
68
128
  get blockTypeHeader(): BlockType;
69
129
  /**
70
- * The total overhead of the block, including encryption overhead
71
- * For encrypted blocks, the overhead is just the ECIES overhead since the
72
- * encryption header is part of the data buffer
130
+ * The total overhead of the block, including encryption overhead.
131
+ * For encrypted blocks, the overhead is the ECIES overhead since the
132
+ * encryption header is part of the data buffer.
133
+ *
134
+ * Single-recipient uses WITH_LENGTH format (72 bytes fixed overhead):
135
+ * overhead = UINT8_SIZE (encryption type) + idSize + ECIES.WITH_LENGTH.FIXED_OVERHEAD_SIZE
136
+ * = 1 + idSize + 72
137
+ *
138
+ * Multi-recipient uses MULTIPLE format:
139
+ * overhead = UINT8_SIZE (encryption type) + calculateECIESMultipleRecipientOverhead()
140
+ * = 1 + 74 + (recipientCount * (idSize + 60))
141
+ *
142
+ * @see Requirements 2.3, 3.3, 5.4
73
143
  */
74
144
  get layerOverheadSize(): number;
75
145
  /**
@@ -81,7 +151,15 @@ export declare class EncryptedBlock<TID extends PlatformID = Uint8Array> extends
81
151
  */
82
152
  get layerPayload(): Uint8Array;
83
153
  /**
84
- * Get the length of the payload including padding
154
+ * Get the length of the encrypted payload (excluding header and padding).
155
+ *
156
+ * For encrypted blocks, the payload is the actual encrypted data portion.
157
+ * This is calculated as: total data length - header overhead
158
+ *
159
+ * Note: This returns the encrypted data size, not the original plaintext size.
160
+ * Use lengthBeforeEncryption for the original data size.
161
+ *
162
+ * @see Requirements 2.2
85
163
  */
86
164
  get layerPayloadSize(): number;
87
165
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"encrypted.d.ts","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/blocks/encrypted.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"encrypted.d.ts","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/blocks/encrypted.ts"],"names":[],"mappings":"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"}
@@ -4,7 +4,6 @@ exports.EncryptedBlock = void 0;
4
4
  /* eslint-disable @typescript-eslint/no-explicit-any */
5
5
  const ecies_lib_1 = require("@digitaldefiance/ecies-lib");
6
6
  const browserConfig_1 = require("../browserConfig");
7
- const constants_1 = require("../constants");
8
7
  const encryptedBlockMetadata_1 = require("../encryptedBlockMetadata");
9
8
  const blockAccessErrorType_1 = require("../enumerations/blockAccessErrorType");
10
9
  const blockEncryptionType_1 = require("../enumerations/blockEncryptionType");
@@ -13,20 +12,76 @@ const blockType_1 = require("../enumerations/blockType");
13
12
  const blockValidationErrorType_1 = require("../enumerations/blockValidationErrorType");
14
13
  const block_1 = require("../errors/block");
15
14
  const service_provider_1 = require("../services/service.provider");
16
- const serviceLocator_1 = require("../services/serviceLocator");
17
15
  const ephemeral_1 = require("./ephemeral");
18
16
  /**
19
17
  * Base class for encrypted blocks.
20
18
  * Adds encryption-specific header data and overhead calculations.
21
19
  *
20
+ * BrightChain adopts ecies-lib's versioned encryption format as the canonical standard.
21
+ *
22
22
  * Block Structure:
23
23
  * [Layer 0 Header][Layer 1 Header][...][Encryption Header][Encrypted Payload][Padding]
24
24
  *
25
- * Single Encryption Header:
26
- * [Encryption Type (1 byte)][Recipient GUID (16 bytes)][Ephemeral Public Key (65 bytes)][IV (16 bytes)][Auth Tag (16 bytes)][Data]
25
+ * ═══════════════════════════════════════════════════════════════════════════════════════
26
+ * SINGLE-RECIPIENT ENCRYPTION (WITH_LENGTH format, type 0x42)
27
+ * ═══════════════════════════════════════════════════════════════════════════════════════
28
+ *
29
+ * BrightChain uses WITH_LENGTH format for single-recipient encryption because:
30
+ * 1. The data length field enables streaming decryption
31
+ * 2. It's only 8 bytes more than BASIC
32
+ * 3. Block sizes are known, making length verification valuable
33
+ *
34
+ * Byte Layout:
35
+ * ┌─────────────────────────────────────────────────────────────────────────────────────┐
36
+ * │ [EncType][RecipientID][Version][CipherSuite][Type][PubKey][IV][AuthTag][Len][Data] │
37
+ * │ [1 ][idSize ][1 ][1 ][1 ][33 ][12][16 ][8 ][...] │
38
+ * └─────────────────────────────────────────────────────────────────────────────────────┘
39
+ *
40
+ * | Offset | Size | Field | Description |
41
+ * |-------------|--------|------------------|------------------------------------------|
42
+ * | 0 | 1 | EncryptionType | BlockEncryptionType.SingleRecipient (1) |
43
+ * | 1 | idSize | RecipientID | BrightChain routing ID |
44
+ * | 1+idSize | 1 | Version | Protocol version (0x01) |
45
+ * | 2+idSize | 1 | CipherSuite | AES-256-GCM (0x01) |
46
+ * | 3+idSize | 1 | EncryptionType | WITH_LENGTH (0x42) |
47
+ * | 4+idSize | 33 | EphemeralPubKey | Compressed secp256k1 public key |
48
+ * | 37+idSize | 12 | IV | Initialization vector (NIST SP 800-38D) |
49
+ * | 49+idSize | 16 | AuthTag | GCM authentication tag |
50
+ * | 65+idSize | 8 | DataLength | Original data length (big-endian) |
51
+ * | 73+idSize | ... | EncryptedData | Ciphertext |
52
+ *
53
+ * Total overhead: 1 + idSize + ECIES.WITH_LENGTH.FIXED_OVERHEAD_SIZE = 1 + idSize + 72
54
+ * Default (GUID, idSize=16): 1 + 16 + 72 = 89 bytes
55
+ * ObjectID (idSize=12): 1 + 12 + 72 = 85 bytes
56
+ *
57
+ * ═══════════════════════════════════════════════════════════════════════════════════════
58
+ * MULTI-RECIPIENT ENCRYPTION (MULTIPLE format, type 0x63)
59
+ * ═══════════════════════════════════════════════════════════════════════════════════════
60
+ *
61
+ * Byte Layout:
62
+ * ┌─────────────────────────────────────────────────────────────────────────────────────┐
63
+ * │ [EncType][Ver][CS][PubKey][IV][Tag][Len][Count][RecipientEntries...][EncryptedData] │
64
+ * │ [1 ][1 ][1 ][33 ][12][16 ][8 ][2 ][variable ][...] │
65
+ * └─────────────────────────────────────────────────────────────────────────────────────┘
27
66
  *
28
- * Multi Encryption Header:
29
- * [Encryption Type (1 byte)][Data Length (8 bytes)][Recipient count (2 bytes)][Recipient GUIDs (16 bytes * recipientCount)][Recipient keys (129 bytes)][Data]
67
+ * Recipient Entry Layout (per recipient):
68
+ * | Offset | Size | Field | Description |
69
+ * |-------------|--------|---------------|-------------------------------------------|
70
+ * | 0 | idSize | RecipientID | Recipient identifier |
71
+ * | idSize | 12 | KeyIV | IV for this recipient's key encryption |
72
+ * | idSize+12 | 16 | KeyAuthTag | Auth tag for key encryption |
73
+ * | idSize+28 | 32 | EncryptedKey | Encrypted symmetric key |
74
+ *
75
+ * Per-recipient overhead: idSize + ECIES.MULTIPLE.ENCRYPTED_KEY_SIZE = idSize + 60
76
+ *
77
+ * Total overhead formula:
78
+ * 1 + ECIES.MULTIPLE.FIXED_OVERHEAD_SIZE + DATA_LENGTH_SIZE + RECIPIENT_COUNT_SIZE
79
+ * + (recipientCount * (idSize + ENCRYPTED_KEY_SIZE))
80
+ * = 1 + 64 + 8 + 2 + (recipientCount * (idSize + 60))
81
+ * = 75 + (recipientCount * (idSize + 60))
82
+ *
83
+ * @see design.md for complete format specification
84
+ * @see Requirements 2.2, 2.3, 3.3, 8.4
30
85
  */
31
86
  class EncryptedBlock extends ephemeral_1.EphemeralBlock {
32
87
  /**
@@ -42,6 +97,8 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
42
97
  constructor(type, dataType, data, checksum, metadata, recipientWithKey, canRead = true, canPersist = true) {
43
98
  super(type, dataType, data, checksum, metadata, canRead, canPersist);
44
99
  this._cachedEncryptionDetails = undefined;
100
+ this._serviceProvider = service_provider_1.ServiceProvider.getInstance();
101
+ this._idProvider = this._serviceProvider.idProvider;
45
102
  // Read encryption type directly from data to avoid circular dependency
46
103
  const blockEncryptionType = data[0];
47
104
  if (metadata.encryptionType !== blockEncryptionType ||
@@ -50,14 +107,12 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
50
107
  }
51
108
  this._encryptionType = blockEncryptionType;
52
109
  if (blockEncryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient) {
53
- const recipientIdBytes = data.subarray(constants_1.ENCRYPTION.ENCRYPTION_TYPE_SIZE, constants_1.ENCRYPTION.ENCRYPTION_TYPE_SIZE + constants_1.ENCRYPTION.RECIPIENT_ID_SIZE);
54
- // Ensure we have exactly 16 bytes for the GUID
55
- if (recipientIdBytes.length !== 16) {
110
+ const recipientIdBytes = data.subarray(ecies_lib_1.UINT8_SIZE, ecies_lib_1.UINT8_SIZE + this._idProvider.byteLength);
111
+ // Ensure we have exactly the expected bytes for the recipient ID
112
+ if (recipientIdBytes.length !== this._idProvider.byteLength) {
56
113
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidRecipientIds);
57
114
  }
58
- this._recipients = [
59
- service_provider_1.ServiceProvider.getInstance().idProvider.fromBytes(recipientIdBytes),
60
- ];
115
+ this._recipients = [this._idProvider.fromBytes(recipientIdBytes)];
61
116
  }
62
117
  else {
63
118
  const details = this
@@ -78,7 +133,7 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
78
133
  }
79
134
  else {
80
135
  // For Guid objects, get the bytes using the idProvider
81
- const result = service_provider_1.ServiceProvider.getInstance().idProvider.toBytes(r);
136
+ const result = this._idProvider.toBytes(r);
82
137
  rBytes = result;
83
138
  }
84
139
  return (0, ecies_lib_1.arraysEqual)(rBytes, recipientWithKey.idBytes);
@@ -133,15 +188,15 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
133
188
  const encryptionType = this.encryptionType;
134
189
  if (encryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient) {
135
190
  const headerData = new Uint8Array(this.layerHeaderData.buffer.slice(this.layerHeaderData.byteOffset +
136
- constants_1.ENCRYPTION.ENCRYPTION_TYPE_SIZE +
137
- constants_1.ENCRYPTION.RECIPIENT_ID_SIZE, this.layerHeaderData.byteOffset + this.layerHeaderData.byteLength));
191
+ ecies_lib_1.UINT8_SIZE +
192
+ this._idProvider.byteLength, this.layerHeaderData.byteOffset + this.layerHeaderData.byteLength));
138
193
  this._cachedEncryptionDetails =
139
- serviceLocator_1.ServiceLocator.getServiceProvider().eciesService.parseSingleEncryptedHeader(ecies_lib_1.EciesEncryptionTypeEnum.Single, headerData);
194
+ this._serviceProvider.eciesService.parseSingleEncryptedHeader(ecies_lib_1.EciesEncryptionTypeEnum.WithLength, headerData);
140
195
  }
141
196
  else if (encryptionType === blockEncryptionType_1.BlockEncryptionType.MultiRecipient) {
142
- const headerData = new Uint8Array(this.layerHeaderData.buffer.slice(this.layerHeaderData.byteOffset + constants_1.ENCRYPTION.ENCRYPTION_TYPE_SIZE, this.layerHeaderData.byteOffset + this.layerHeaderData.byteLength));
197
+ const headerData = new Uint8Array(this.layerHeaderData.buffer.slice(this.layerHeaderData.byteOffset + ecies_lib_1.UINT8_SIZE, this.layerHeaderData.byteOffset + this.layerHeaderData.byteLength));
143
198
  this._cachedEncryptionDetails =
144
- serviceLocator_1.ServiceLocator.getServiceProvider().eciesService.parseMultiEncryptedHeader(headerData);
199
+ this._serviceProvider.eciesService.parseMultiEncryptedHeader(headerData);
145
200
  }
146
201
  else {
147
202
  throw new block_1.BlockError(blockErrorType_1.BlockErrorType.UnexpectedEncryptedBlockType);
@@ -165,8 +220,8 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
165
220
  throw new block_1.BlockError(blockErrorType_1.BlockErrorType.CreatorPrivateKeyRequired);
166
221
  }
167
222
  return (this.encryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient
168
- ? await serviceLocator_1.ServiceLocator.getServiceProvider().blockService.decrypt(this.recipientWithKey, this, newBlockType)
169
- : await serviceLocator_1.ServiceLocator.getServiceProvider().blockService.decryptMultiple(this.recipientWithKey, this));
223
+ ? await this._serviceProvider.blockService.decrypt(this.recipientWithKey, this, newBlockType)
224
+ : await this._serviceProvider.blockService.decryptMultiple(this.recipientWithKey, this));
170
225
  }
171
226
  /**
172
227
  * The block type stored in the header
@@ -178,17 +233,33 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
178
233
  return this.layerHeaderData[0];
179
234
  }
180
235
  /**
181
- * The total overhead of the block, including encryption overhead
182
- * For encrypted blocks, the overhead is just the ECIES overhead since the
183
- * encryption header is part of the data buffer
236
+ * The total overhead of the block, including encryption overhead.
237
+ * For encrypted blocks, the overhead is the ECIES overhead since the
238
+ * encryption header is part of the data buffer.
239
+ *
240
+ * Single-recipient uses WITH_LENGTH format (72 bytes fixed overhead):
241
+ * overhead = UINT8_SIZE (encryption type) + idSize + ECIES.WITH_LENGTH.FIXED_OVERHEAD_SIZE
242
+ * = 1 + idSize + 72
243
+ *
244
+ * Multi-recipient uses MULTIPLE format:
245
+ * overhead = UINT8_SIZE (encryption type) + calculateECIESMultipleRecipientOverhead()
246
+ * = 1 + 74 + (recipientCount * (idSize + 60))
247
+ *
248
+ * @see Requirements 2.3, 3.3, 5.4
184
249
  */
185
250
  get layerOverheadSize() {
186
- return ((this.encryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient
187
- ? constants_1.ECIES.OVERHEAD_SIZE +
188
- constants_1.ENCRYPTION.ENCRYPTION_TYPE_SIZE +
189
- constants_1.ENCRYPTION.RECIPIENT_ID_SIZE
190
- : (0, browserConfig_1.calculateECIESMultipleRecipientOverhead)(this.encryptionDetails
191
- .recipientCount, false)) + constants_1.ENCRYPTION.ENCRYPTION_TYPE_SIZE);
251
+ if (this.encryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient) {
252
+ // Single-recipient: [EncType(1)][RecipientID(idSize)][ecies-lib WITH_LENGTH header(72)]
253
+ return (ecies_lib_1.UINT8_SIZE +
254
+ this._idProvider.byteLength +
255
+ ecies_lib_1.ECIES.WITH_LENGTH.FIXED_OVERHEAD_SIZE);
256
+ }
257
+ else {
258
+ // Multi-recipient: [EncType(1)][ecies-lib MULTIPLE header]
259
+ return (ecies_lib_1.UINT8_SIZE +
260
+ (0, browserConfig_1.calculateECIESMultipleRecipientOverhead)(this.encryptionDetails
261
+ .recipientCount, true, this._idProvider.byteLength));
262
+ }
192
263
  }
193
264
  /**
194
265
  * Get this layer's header data (encryption metadata)
@@ -212,12 +283,21 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
212
283
  return this.data.subarray(headerLength, headerLength + this.layerPayloadSize);
213
284
  }
214
285
  /**
215
- * Get the length of the payload including padding
286
+ * Get the length of the encrypted payload (excluding header and padding).
287
+ *
288
+ * For encrypted blocks, the payload is the actual encrypted data portion.
289
+ * This is calculated as: total data length - header overhead
290
+ *
291
+ * Note: This returns the encrypted data size, not the original plaintext size.
292
+ * Use lengthBeforeEncryption for the original data size.
293
+ *
294
+ * @see Requirements 2.2
216
295
  */
217
296
  get layerPayloadSize() {
218
- return this.encryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient
219
- ? constants_1.ECIES.OVERHEAD_SIZE
220
- : constants_1.ECIES.MULTIPLE.ENCRYPTED_MESSAGE_OVERHEAD_SIZE;
297
+ // The payload is everything after the header up to the end of encrypted data
298
+ // For encrypted blocks, we use lengthBeforeEncryption to determine the actual
299
+ // encrypted content size (the ciphertext is the same size as plaintext in GCM mode)
300
+ return this.lengthBeforeEncryption;
221
301
  }
222
302
  /**
223
303
  * Get the total encrypted length including headers and payload
@@ -232,21 +312,22 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
232
312
  async validateAsync() {
233
313
  // Call parent validation first
234
314
  await super.validateAsync();
235
- // Validate encryption header lengths
236
- if (this.layerHeaderData.length !== constants_1.ECIES.OVERHEAD_SIZE) {
315
+ // Validate encryption header length matches the calculated overhead
316
+ const expectedHeaderLength = this.layerOverheadSize;
317
+ if (this.layerHeaderData.length !== expectedHeaderLength) {
237
318
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidEncryptionHeaderLength);
238
319
  }
239
320
  if (this.encryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient) {
240
321
  const details = this
241
322
  .encryptionDetails;
242
323
  // Validate individual components
243
- if (details.ephemeralPublicKey.length !== constants_1.ECIES.PUBLIC_KEY_LENGTH) {
324
+ if (details.ephemeralPublicKey.length !== ecies_lib_1.ECIES.PUBLIC_KEY_LENGTH) {
244
325
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidEphemeralPublicKeyLength);
245
326
  }
246
- if (details.iv.length !== constants_1.ECIES.IV_LENGTH) {
327
+ if (details.iv.length !== ecies_lib_1.ECIES.IV_SIZE) {
247
328
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidIVLength);
248
329
  }
249
- if (details.authTag.length !== constants_1.ECIES.AUTH_TAG_LENGTH) {
330
+ if (details.authTag.length !== ecies_lib_1.ECIES.AUTH_TAG_SIZE) {
250
331
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidAuthTagLength);
251
332
  }
252
333
  }
@@ -260,13 +341,11 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
260
341
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidRecipientIds);
261
342
  }
262
343
  else if (details.recipientIds
263
- .map((id) => id instanceof ecies_lib_1.Guid
264
- ? service_provider_1.ServiceProvider.getInstance().idProvider.toBytes(id)
265
- : id)
266
- .some((id) => id.length !== constants_1.default['GUID_SIZE'])) {
344
+ .map((id) => this._idProvider.toBytes(id))
345
+ .some((id) => id.length !== id.byteLength)) {
267
346
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidRecipientIds);
268
347
  }
269
- else if (details.recipientKeys.some((k) => k.length !== constants_1.ECIES.MULTIPLE.ENCRYPTED_KEY_SIZE)) {
348
+ else if (details.recipientKeys.some((k) => k.length !== ecies_lib_1.ECIES.MULTIPLE.ENCRYPTED_KEY_SIZE)) {
270
349
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidRecipientKeys);
271
350
  }
272
351
  }
@@ -276,7 +355,7 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
276
355
  }
277
356
  // Validate actual data length
278
357
  if (this.lengthBeforeEncryption >
279
- service_provider_1.ServiceProvider.getInstance().blockCapacityCalculator.calculateCapacity({
358
+ this._serviceProvider.blockCapacityCalculator.calculateCapacity({
280
359
  blockSize: this.blockSize,
281
360
  blockType: this.blockType,
282
361
  encryptionType: this.encryptionType,
@@ -296,20 +375,21 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
296
375
  validateSync() {
297
376
  // Call parent validation first
298
377
  super.validateSync();
299
- // Validate encryption header lengths
300
- if (this.layerHeaderData.length !== constants_1.ECIES.OVERHEAD_SIZE) {
378
+ // Validate encryption header length matches the calculated overhead
379
+ const expectedHeaderLength = this.layerOverheadSize;
380
+ if (this.layerHeaderData.length !== expectedHeaderLength) {
301
381
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidEncryptionHeaderLength);
302
382
  }
303
383
  if (this._encryptionType === blockEncryptionType_1.BlockEncryptionType.SingleRecipient) {
304
384
  const details = this.encryptionDetails;
305
385
  // Validate individual components
306
- if (details.ephemeralPublicKey.length !== constants_1.ECIES.PUBLIC_KEY_LENGTH) {
386
+ if (details.ephemeralPublicKey.length !== ecies_lib_1.ECIES.PUBLIC_KEY_LENGTH) {
307
387
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidEphemeralPublicKeyLength);
308
388
  }
309
- if (details.iv.length !== constants_1.ECIES.IV_LENGTH) {
389
+ if (details.iv.length !== ecies_lib_1.ECIES.IV_SIZE) {
310
390
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidIVLength);
311
391
  }
312
- if (details.authTag.length !== constants_1.ECIES.AUTH_TAG_LENGTH) {
392
+ if (details.authTag.length !== ecies_lib_1.ECIES.AUTH_TAG_SIZE) {
313
393
  throw new block_1.BlockValidationError(blockValidationErrorType_1.BlockValidationErrorType.InvalidAuthTagLength);
314
394
  }
315
395
  }
@@ -331,7 +411,7 @@ class EncryptedBlock extends ephemeral_1.EphemeralBlock {
331
411
  }
332
412
  // Validate actual data length
333
413
  if (this.lengthBeforeEncryption >
334
- service_provider_1.ServiceProvider.getInstance().blockCapacityCalculator.calculateCapacity({
414
+ this._serviceProvider.blockCapacityCalculator.calculateCapacity({
335
415
  blockSize: this.blockSize,
336
416
  blockType: this.blockType,
337
417
  encryptionType: this.encryptionType,