@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.
- package/brightchain-lib/README.md +39 -1
- package/package.json +2 -2
- package/src/index.d.ts +1 -1
- package/src/index.d.ts.map +1 -1
- package/src/index.js +2 -3
- package/src/index.js.map +1 -1
- package/src/lib/access/ecies.d.ts.map +1 -1
- package/src/lib/access/ecies.js +3 -3
- package/src/lib/access/ecies.js.map +1 -1
- package/src/lib/blocks/encrypted.d.ts +87 -9
- package/src/lib/blocks/encrypted.d.ts.map +1 -1
- package/src/lib/blocks/encrypted.js +130 -50
- package/src/lib/blocks/encrypted.js.map +1 -1
- package/src/lib/blocks/encryptedBlockFactory.d.ts.map +1 -1
- package/src/lib/blocks/encryptedBlockFactory.js +13 -13
- package/src/lib/blocks/encryptedBlockFactory.js.map +1 -1
- package/src/lib/blocks/ephemeral.d.ts.map +1 -1
- package/src/lib/blocks/ephemeral.js +3 -3
- package/src/lib/blocks/ephemeral.js.map +1 -1
- package/src/lib/brightChain.js +2 -2
- package/src/lib/brightChain.js.map +1 -1
- package/src/lib/browserBrightChain.js +2 -2
- package/src/lib/browserBrightChain.js.map +1 -1
- package/src/lib/browserConfig.d.ts +30 -2
- package/src/lib/browserConfig.d.ts.map +1 -1
- package/src/lib/browserConfig.js +45 -7
- package/src/lib/browserConfig.js.map +1 -1
- package/src/lib/constants.d.ts +6 -200
- package/src/lib/constants.d.ts.map +1 -1
- package/src/lib/constants.js +7 -138
- package/src/lib/constants.js.map +1 -1
- package/src/lib/documents/network/networkDocument.d.ts +4 -4
- package/src/lib/documents/network/networkDocument.d.ts.map +1 -1
- package/src/lib/ecies-config.d.ts +1 -1
- package/src/lib/ecies-config.d.ts.map +1 -1
- package/src/lib/ecies-config.js +8 -8
- package/src/lib/ecies-config.js.map +1 -1
- package/src/lib/encryptedBlockMetadata.d.ts.map +1 -1
- package/src/lib/encryptedBlockMetadata.js +2 -2
- package/src/lib/encryptedBlockMetadata.js.map +1 -1
- package/src/lib/index.d.ts +0 -2
- package/src/lib/index.d.ts.map +1 -1
- package/src/lib/index.js +0 -2
- package/src/lib/index.js.map +1 -1
- package/src/lib/interfaces/clusterKeys.d.ts +2 -2
- package/src/lib/interfaces/clusterKeys.d.ts.map +1 -1
- package/src/lib/interfaces/constants.d.ts +2 -60
- package/src/lib/interfaces/constants.d.ts.map +1 -1
- package/src/lib/interfaces/member/operational.d.ts +3 -3
- package/src/lib/interfaces/member/operational.d.ts.map +1 -1
- package/src/lib/interfaces/messaging/messageSystemConfig.d.ts +3 -0
- package/src/lib/interfaces/messaging/messageSystemConfig.d.ts.map +1 -1
- package/src/lib/interfaces/messaging/messageSystemConfig.js +14 -0
- package/src/lib/interfaces/messaging/messageSystemConfig.js.map +1 -1
- package/src/lib/interfaces/network/node.d.ts +5 -5
- package/src/lib/interfaces/network/node.d.ts.map +1 -1
- package/src/lib/interfaces/storage/blockStore.d.ts +6 -0
- package/src/lib/interfaces/storage/blockStore.d.ts.map +1 -1
- package/src/lib/schemas/network/networkDocumentSchema.js +1 -1
- package/src/lib/schemas/network/networkDocumentSchema.js.map +1 -1
- package/src/lib/services/blockCapacity.service.d.ts.map +1 -1
- package/src/lib/services/blockCapacity.service.js +17 -15
- package/src/lib/services/blockCapacity.service.js.map +1 -1
- package/src/lib/services/blockService.d.ts.map +1 -1
- package/src/lib/services/blockService.js +10 -7
- package/src/lib/services/blockService.js.map +1 -1
- package/src/lib/services/cblService.d.ts.map +1 -1
- package/src/lib/services/cblService.js +12 -12
- package/src/lib/services/cblService.js.map +1 -1
- package/src/lib/services/checksum.service.d.ts.map +1 -1
- package/src/lib/services/checksum.service.js +2 -2
- package/src/lib/services/checksum.service.js.map +1 -1
- package/src/lib/services/fec.service.js +6 -6
- package/src/lib/services/fec.service.js.map +1 -1
- package/src/lib/services/index.d.ts +1 -0
- package/src/lib/services/index.d.ts.map +1 -1
- package/src/lib/services/index.js +1 -0
- package/src/lib/services/index.js.map +1 -1
- package/src/lib/services/messaging/messageCBLService.d.ts +1 -0
- package/src/lib/services/messaging/messageCBLService.d.ts.map +1 -1
- package/src/lib/services/messaging/messageCBLService.js +15 -14
- package/src/lib/services/messaging/messageCBLService.js.map +1 -1
- package/src/lib/services/sealing.service.d.ts.map +1 -1
- package/src/lib/services/sealing.service.js +3 -4
- package/src/lib/services/sealing.service.js.map +1 -1
- package/src/lib/services/tupleStorageService.d.ts +75 -0
- package/src/lib/services/tupleStorageService.d.ts.map +1 -0
- package/src/lib/services/tupleStorageService.js +194 -0
- package/src/lib/services/tupleStorageService.js.map +1 -0
- package/src/lib/simpleBrightChain.d.ts.map +1 -1
- package/src/lib/simpleBrightChain.js +1 -2
- package/src/lib/simpleBrightChain.js.map +1 -1
- package/src/lib/types/checksum.d.ts.map +1 -1
- package/src/lib/types/checksum.js +6 -7
- package/src/lib/types/checksum.js.map +1 -1
- package/src/lib/utils/validator.js +2 -2
- package/src/lib/utils/validator.js.map +1 -1
- package/src/lib/brightChainConsts.d.ts +0 -51
- package/src/lib/brightChainConsts.d.ts.map +0 -1
- package/src/lib/brightChainConsts.js +0 -26
- package/src/lib/brightChainConsts.js.map +0 -1
- package/src/lib/pbkdf2Profiles.d.ts +0 -6
- package/src/lib/pbkdf2Profiles.d.ts.map +0 -1
- package/src/lib/pbkdf2Profiles.js +0 -3
- 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
|
-
###
|
|
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.
|
|
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.
|
|
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,
|
|
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
|
package/src/index.d.ts.map
CHANGED
|
@@ -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,
|
|
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.
|
|
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,
|
|
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;
|
|
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"}
|
package/src/lib/access/ecies.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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.
|
|
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,
|
|
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
|
-
*
|
|
19
|
-
*
|
|
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
|
-
*
|
|
22
|
-
*
|
|
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
|
|
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
|
|
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":"AACA,OAAO,EAIL,2BAA2B,EAC3B,4BAA4B,EAC5B,MAAM,EACN,KAAK,UAAU,EAChB,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"encrypted.d.ts","sourceRoot":"","sources":["../../../../../brightchain-lib/src/lib/blocks/encrypted.ts"],"names":[],"mappings":"AACA,OAAO,EAIL,2BAA2B,EAC3B,4BAA4B,EAC5B,MAAM,EACN,sBAAsB,EAEtB,KAAK,UAAU,EAChB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE1E,OAAO,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AACtD,OAAO,EACL,SAAS,EAGV,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,qBAAa,cAAc,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU,CAC7D,SAAQ,cAAc,CAAC,GAAG,CAC1B,YAAW,eAAe,CAAC,GAAG,CAAC;IAE/B,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,mBAAmB,CAAC;IACxD,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3C,SAAS,CAAC,QAAQ,CAAC,iBAAiB,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;IAClD,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,eAAe,CAAC,GAAG,CAAC,CAAC;IAC1D,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5D,SAAS,CAAC,wBAAwB,CAAC,EAC/B,4BAA4B,GAC5B,2BAA2B,CAAC,GAAG,CAAC,CAAa;IAEjD;;;;;;;;;OASG;gBAED,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,aAAa,EACvB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,sBAAsB,CAAC,GAAG,CAAC,EACrC,gBAAgB,EAAE,MAAM,CAAC,GAAG,CAAC,EAC7B,OAAO,UAAO,EACd,UAAU,UAAO;IA4DnB;;OAEG;WAC0B,IAAI,CAAC,GAAG,SAAS,UAAU,GAAG,UAAU,EACnE,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,aAAa,EACvB,SAAS,EAAE,SAAS,EACpB,IAAI,EAAE,UAAU,EAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EACpB,WAAW,CAAC,EAAE,IAAI,EAClB,sBAAsB,CAAC,EAAE,MAAM,EAC/B,OAAO,CAAC,EAAE,OAAO,EACjB,UAAU,CAAC,EAAE,OAAO,EACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC,GAAG,CAAC,EAC9B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;IAuB/B;;;OAGG;IACa,UAAU,IAAI,OAAO;IAKrB,eAAe,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO;IAI1C,OAAO,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC;IAI9C;;OAEG;IACH,IAAW,cAAc,IAAI,mBAAmB,CAE/C;IAED;;OAEG;IACH,IAAW,UAAU,IAAI,KAAK,CAAC,GAAG,CAAC,CAElC;IAED,IAAW,gBAAgB,IAAI,MAAM,CAAC,GAAG,CAAC,CAEzC;IAED;;OAEG;IACH,IAAW,iBAAiB,IACxB,4BAA4B,GAC5B,2BAA2B,CAAC,GAAG,CAAC,CAqCnC;IAEY,OAAO,CAAC,CAAC,SAAS,eAAe,CAAC,GAAG,CAAC,EACjD,YAAY,EAAE,SAAS,GACtB,OAAO,CAAC,CAAC,CAAC;IAuBb;;OAEG;IACH,IAAW,eAAe,IAAI,SAAS,CAKtC;IAED;;;;;;;;;;;;;;OAcG;IACH,IAAoB,iBAAiB,IAAI,MAAM,CAoB9C;IAED;;OAEG;IACH,IAAoB,eAAe,IAAI,UAAU,CAOhD;IAED;;OAEG;IACH,IAAoB,YAAY,IAAI,UAAU,CAS7C;IAED;;;;;;;;;;OAUG;IACH,IAAoB,gBAAgB,IAAI,MAAM,CAK7C;IAED;;OAEG;IACH,IAAW,eAAe,IAAI,MAAM,CAEnC;IAED;;;OAGG;IACmB,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC;IA6FpD;;;OAGG;IACa,YAAY,IAAI,IAAI;IA+EpC;;;OAGG;IACa,QAAQ,IAAI,IAAI;CAGjC"}
|
|
@@ -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
|
-
*
|
|
26
|
-
*
|
|
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
|
-
*
|
|
29
|
-
*
|
|
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(
|
|
54
|
-
// Ensure we have exactly
|
|
55
|
-
if (recipientIdBytes.length !==
|
|
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 =
|
|
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
|
-
|
|
137
|
-
|
|
191
|
+
ecies_lib_1.UINT8_SIZE +
|
|
192
|
+
this._idProvider.byteLength, this.layerHeaderData.byteOffset + this.layerHeaderData.byteLength));
|
|
138
193
|
this._cachedEncryptionDetails =
|
|
139
|
-
|
|
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 +
|
|
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
|
-
|
|
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
|
|
169
|
-
: await
|
|
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
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
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
|
|
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
|
-
|
|
219
|
-
|
|
220
|
-
|
|
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
|
|
236
|
-
|
|
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 !==
|
|
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 !==
|
|
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 !==
|
|
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
|
|
264
|
-
|
|
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 !==
|
|
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
|
-
|
|
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
|
|
300
|
-
|
|
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 !==
|
|
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 !==
|
|
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 !==
|
|
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
|
-
|
|
414
|
+
this._serviceProvider.blockCapacityCalculator.calculateCapacity({
|
|
335
415
|
blockSize: this.blockSize,
|
|
336
416
|
blockType: this.blockType,
|
|
337
417
|
encryptionType: this.encryptionType,
|