spd-lib 1.3.4 → 1.3.5
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/index.d.mts +118 -6
- package/index.d.ts +118 -6
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
package/index.d.mts
CHANGED
|
@@ -25,6 +25,8 @@ interface SPDPayload {
|
|
|
25
25
|
hashAlgorithm?: string;
|
|
26
26
|
argon2Memory?: number;
|
|
27
27
|
argon2Time?: number;
|
|
28
|
+
argon2HashLen?: number;
|
|
29
|
+
hashKeyLen?: number;
|
|
28
30
|
}
|
|
29
31
|
interface SPDLegacyPayload {
|
|
30
32
|
data: SerializedDataEntry[];
|
|
@@ -65,9 +67,26 @@ interface SPDChunkManifest {
|
|
|
65
67
|
totalBytes: number;
|
|
66
68
|
version: number;
|
|
67
69
|
}
|
|
70
|
+
interface SPDIndexEntry {
|
|
71
|
+
name: string;
|
|
72
|
+
decompressedOffset: bigint;
|
|
73
|
+
}
|
|
74
|
+
interface SPDWriterOptions {
|
|
75
|
+
compressionLevel?: number;
|
|
76
|
+
hashAlgorithm?: HashAlgorithm;
|
|
77
|
+
argon2Memory?: number;
|
|
78
|
+
argon2Time?: number;
|
|
79
|
+
}
|
|
80
|
+
interface SPDGetEntryResult {
|
|
81
|
+
value: unknown;
|
|
82
|
+
dataType: SupportedDataType;
|
|
83
|
+
name: string;
|
|
84
|
+
}
|
|
68
85
|
type TypedArray = Uint8Array | Uint16Array | Uint32Array | BigInt64Array | BigUint64Array | Float32Array | Float64Array;
|
|
69
86
|
type SupportedValue = string | number | boolean | unknown[] | TypedArray | Map<unknown, unknown> | Set<unknown> | Date | RegExp | Error | Record<string, unknown>;
|
|
70
87
|
|
|
88
|
+
declare const ARGON2_MEMORY_HIGH = 524288;
|
|
89
|
+
declare const ARGON2_TIME_HIGH = 8;
|
|
71
90
|
declare class SPD {
|
|
72
91
|
private data;
|
|
73
92
|
private keyPair?;
|
|
@@ -80,11 +99,14 @@ declare class SPD {
|
|
|
80
99
|
init(): Promise<void>;
|
|
81
100
|
changePasscode(oldPasscode: string, newPasscode: string): Promise<void>;
|
|
82
101
|
/**
|
|
83
|
-
* Derives a
|
|
84
|
-
* aeadKey (32 B)
|
|
85
|
-
* macKey (32 B)
|
|
102
|
+
* Derives a master secret via Argon2id and splits it into:
|
|
103
|
+
* aeadKey (32 B) — XChaCha20-Poly1305 encryption key
|
|
104
|
+
* macKey (32/64 B) — HMAC-SHA3-512 authentication key (domain-separated)
|
|
105
|
+
*
|
|
106
|
+
* v27+: hashLen=96, macKeyLen=64 (full SHA3-512 output width = 128-bit PQ forgery resistance)
|
|
107
|
+
* v26: hashLen=64, macKeyLen=32 (legacy — pass these explicitly when reading old files)
|
|
86
108
|
*/
|
|
87
|
-
static deriveKeys(passcode: string, salt: Uint8Array, memory?: number, time?: number): Promise<{
|
|
109
|
+
static deriveKeys(passcode: string, salt: Uint8Array, memory?: number, time?: number, hashLen?: number, macKeyLen?: number): Promise<{
|
|
88
110
|
aeadKey: Uint8Array;
|
|
89
111
|
macKey: Uint8Array;
|
|
90
112
|
}>;
|
|
@@ -127,8 +149,28 @@ declare class SPD {
|
|
|
127
149
|
/**
|
|
128
150
|
* Saves to file using streaming I/O — supports files larger than 2 GB.
|
|
129
151
|
* Format: [8B LE uint64 plaintext length][64B HMAC-SHA3-512][zlib(plaintext)]
|
|
152
|
+
*
|
|
153
|
+
* Also writes a `.spdi` index sidecar alongside the output file that allows
|
|
154
|
+
* `SPD.getEntry()` to locate entries without decrypting the whole file.
|
|
130
155
|
*/
|
|
131
156
|
saveToFileStreaming(outputPath: string, passcode: string): Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Computes the decompressed byte offset of each entry within a binary plaintext buffer.
|
|
159
|
+
* The offset points to the start of that entry's nameLen byte.
|
|
160
|
+
*/
|
|
161
|
+
private static buildOffsetIndex;
|
|
162
|
+
/**
|
|
163
|
+
* Writes a `.spdi` index sidecar file for fast on-demand entry lookup.
|
|
164
|
+
* Format:
|
|
165
|
+
* [4B magic "SPDI"][4B version][8B entryCount][32B HMAC-SHA3-256 of body]
|
|
166
|
+
* for each entry: [1B nameLen][name bytes][8B LE uint64 decompressedOffset]
|
|
167
|
+
*/
|
|
168
|
+
private static writeIndexFile;
|
|
169
|
+
/**
|
|
170
|
+
* Reads and validates a `.spdi` index sidecar.
|
|
171
|
+
* Returns null if the file doesn't exist or the HMAC fails (falls back to scan).
|
|
172
|
+
*/
|
|
173
|
+
private static readIndexFile;
|
|
132
174
|
saveData(passcode?: string): Promise<string>;
|
|
133
175
|
/**
|
|
134
176
|
* Splits the payload into base64 chunks for chunked internet transfer.
|
|
@@ -170,9 +212,24 @@ declare class SPD {
|
|
|
170
212
|
* });
|
|
171
213
|
*/
|
|
172
214
|
static extractFromFileStreaming(filePath: string, passcode: string, tmpDir: string, callback: (name: string, value: unknown) => Promise<void> | void): Promise<void>;
|
|
215
|
+
/**
|
|
216
|
+
* On-demand disk lookup — decrypts and returns a single named entry from a
|
|
217
|
+
* binary `.spd` file (written by `saveToFileStreaming`) without loading the
|
|
218
|
+
* whole file into RAM.
|
|
219
|
+
*
|
|
220
|
+
* Uses a `.spdi` index sidecar (written alongside by `saveToFileStreaming`)
|
|
221
|
+
* for fast offset lookup when present. Falls back to a sequential scan if
|
|
222
|
+
* the sidecar is missing or its HMAC fails.
|
|
223
|
+
*
|
|
224
|
+
* The full plaintext MAC is always verified before any entry is decrypted —
|
|
225
|
+
* unauthenticated reads are never returned.
|
|
226
|
+
*
|
|
227
|
+
* RAM usage is bounded to ~one entry's worth of bytes at any time.
|
|
228
|
+
*/
|
|
229
|
+
static getEntry(filePath: string, passcode: string, name: string): Promise<SPDGetEntryResult>;
|
|
173
230
|
static loadFromString(data: string, passcode: string): Promise<SPD>;
|
|
174
231
|
static loadFromChunks(chunks: string[], passcode: string): Promise<SPD>;
|
|
175
|
-
static derivePBK(passcode: string, salt: Uint8Array, memory?: number, time?: number): Promise<PBKResult>;
|
|
232
|
+
static derivePBK(passcode: string, salt: Uint8Array, memory?: number, time?: number, hashLen?: number): Promise<PBKResult>;
|
|
176
233
|
static decryptSalt(encryptedSalt: number[], saltNonce: number[], wrapSalt: number[], passcode: string, memory?: number, time?: number): Promise<Uint8Array>;
|
|
177
234
|
static encryptSalt(salt: Uint8Array, passcode: string): Promise<EncryptedSaltResult>;
|
|
178
235
|
static toBase64(data: Uint8Array | Buffer): string;
|
|
@@ -265,4 +322,59 @@ declare class SPDVault {
|
|
|
265
322
|
destroy(): void;
|
|
266
323
|
}
|
|
267
324
|
|
|
268
|
-
|
|
325
|
+
/**
|
|
326
|
+
* SPDWriter — streaming, disk-backed binary SPD writer.
|
|
327
|
+
*
|
|
328
|
+
* Writes entries one at a time to disk as they are encrypted, so the full
|
|
329
|
+
* plaintext never exists in RAM simultaneously. Works on any device regardless
|
|
330
|
+
* of available memory.
|
|
331
|
+
*
|
|
332
|
+
* Usage:
|
|
333
|
+
* const writer = new SPDWriter('./output.spd', 'MyStr0ng!Passphrase#2024');
|
|
334
|
+
* await writer.init();
|
|
335
|
+
* await writer.addEntry('username', 'alice');
|
|
336
|
+
* await writer.addEntry('config', { theme: 'dark' });
|
|
337
|
+
* await writer.finalize();
|
|
338
|
+
*
|
|
339
|
+
* After finalize(), a `.spdi` index sidecar is written alongside the output
|
|
340
|
+
* file so that `SPD.getEntry()` can locate entries without a full scan.
|
|
341
|
+
*/
|
|
342
|
+
|
|
343
|
+
declare class SPDWriter {
|
|
344
|
+
private outputPath;
|
|
345
|
+
private passcode;
|
|
346
|
+
private opts;
|
|
347
|
+
private aeadKey?;
|
|
348
|
+
private macKey?;
|
|
349
|
+
private salt?;
|
|
350
|
+
private deflate?;
|
|
351
|
+
private outStream?;
|
|
352
|
+
private hmac?;
|
|
353
|
+
private plaintextOffset;
|
|
354
|
+
private entryCount;
|
|
355
|
+
private indexEntries;
|
|
356
|
+
private finalized;
|
|
357
|
+
private initialized;
|
|
358
|
+
constructor(outputPath: string, passcode: string, opts?: SPDWriterOptions);
|
|
359
|
+
/**
|
|
360
|
+
* Derives keys, opens the output file, and writes the meta block.
|
|
361
|
+
* Must be called before addEntry().
|
|
362
|
+
*/
|
|
363
|
+
init(): Promise<void>;
|
|
364
|
+
/**
|
|
365
|
+
* Encrypts one entry and streams it to disk.
|
|
366
|
+
*/
|
|
367
|
+
addEntry(name: string, value: unknown): Promise<void>;
|
|
368
|
+
/**
|
|
369
|
+
* Flushes the deflate stream, computes the HMAC, patches the file header,
|
|
370
|
+
* and writes the `.spdi` index sidecar.
|
|
371
|
+
*/
|
|
372
|
+
finalize(): Promise<void>;
|
|
373
|
+
/** Zero keys and remove the partial output file if finalize() was never called. */
|
|
374
|
+
destroy(): void;
|
|
375
|
+
/** Write bytes to the deflate stream and update the rolling HMAC + offset. */
|
|
376
|
+
private writeToPlaintext;
|
|
377
|
+
private writeIndexSidecar;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export { ARGON2_MEMORY_HIGH, ARGON2_TIME_HIGH, type DataInput, type EncryptedDataEntry, type EncryptedSaltResult, type HashAlgorithm, type PBKResult, type PQCKey, type PQCKeyResult, SPD, type SPDChunkManifest, type SPDGetEntryResult, type SPDIndexEntry, SPDLegacy, type SPDLegacyPayload, type SPDPayload, SPDVault, SPDWriter, type SPDWriterOptions, SPDLegacy as SPD_LEG, SPDVault as SPD_Vault, type SerializedDataEntry, type SerializedWrappedPayload, type SupportedDataType, type SupportedValue, type TypedArray, type WrappedPayload };
|
package/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ interface SPDPayload {
|
|
|
25
25
|
hashAlgorithm?: string;
|
|
26
26
|
argon2Memory?: number;
|
|
27
27
|
argon2Time?: number;
|
|
28
|
+
argon2HashLen?: number;
|
|
29
|
+
hashKeyLen?: number;
|
|
28
30
|
}
|
|
29
31
|
interface SPDLegacyPayload {
|
|
30
32
|
data: SerializedDataEntry[];
|
|
@@ -65,9 +67,26 @@ interface SPDChunkManifest {
|
|
|
65
67
|
totalBytes: number;
|
|
66
68
|
version: number;
|
|
67
69
|
}
|
|
70
|
+
interface SPDIndexEntry {
|
|
71
|
+
name: string;
|
|
72
|
+
decompressedOffset: bigint;
|
|
73
|
+
}
|
|
74
|
+
interface SPDWriterOptions {
|
|
75
|
+
compressionLevel?: number;
|
|
76
|
+
hashAlgorithm?: HashAlgorithm;
|
|
77
|
+
argon2Memory?: number;
|
|
78
|
+
argon2Time?: number;
|
|
79
|
+
}
|
|
80
|
+
interface SPDGetEntryResult {
|
|
81
|
+
value: unknown;
|
|
82
|
+
dataType: SupportedDataType;
|
|
83
|
+
name: string;
|
|
84
|
+
}
|
|
68
85
|
type TypedArray = Uint8Array | Uint16Array | Uint32Array | BigInt64Array | BigUint64Array | Float32Array | Float64Array;
|
|
69
86
|
type SupportedValue = string | number | boolean | unknown[] | TypedArray | Map<unknown, unknown> | Set<unknown> | Date | RegExp | Error | Record<string, unknown>;
|
|
70
87
|
|
|
88
|
+
declare const ARGON2_MEMORY_HIGH = 524288;
|
|
89
|
+
declare const ARGON2_TIME_HIGH = 8;
|
|
71
90
|
declare class SPD {
|
|
72
91
|
private data;
|
|
73
92
|
private keyPair?;
|
|
@@ -80,11 +99,14 @@ declare class SPD {
|
|
|
80
99
|
init(): Promise<void>;
|
|
81
100
|
changePasscode(oldPasscode: string, newPasscode: string): Promise<void>;
|
|
82
101
|
/**
|
|
83
|
-
* Derives a
|
|
84
|
-
* aeadKey (32 B)
|
|
85
|
-
* macKey (32 B)
|
|
102
|
+
* Derives a master secret via Argon2id and splits it into:
|
|
103
|
+
* aeadKey (32 B) — XChaCha20-Poly1305 encryption key
|
|
104
|
+
* macKey (32/64 B) — HMAC-SHA3-512 authentication key (domain-separated)
|
|
105
|
+
*
|
|
106
|
+
* v27+: hashLen=96, macKeyLen=64 (full SHA3-512 output width = 128-bit PQ forgery resistance)
|
|
107
|
+
* v26: hashLen=64, macKeyLen=32 (legacy — pass these explicitly when reading old files)
|
|
86
108
|
*/
|
|
87
|
-
static deriveKeys(passcode: string, salt: Uint8Array, memory?: number, time?: number): Promise<{
|
|
109
|
+
static deriveKeys(passcode: string, salt: Uint8Array, memory?: number, time?: number, hashLen?: number, macKeyLen?: number): Promise<{
|
|
88
110
|
aeadKey: Uint8Array;
|
|
89
111
|
macKey: Uint8Array;
|
|
90
112
|
}>;
|
|
@@ -127,8 +149,28 @@ declare class SPD {
|
|
|
127
149
|
/**
|
|
128
150
|
* Saves to file using streaming I/O — supports files larger than 2 GB.
|
|
129
151
|
* Format: [8B LE uint64 plaintext length][64B HMAC-SHA3-512][zlib(plaintext)]
|
|
152
|
+
*
|
|
153
|
+
* Also writes a `.spdi` index sidecar alongside the output file that allows
|
|
154
|
+
* `SPD.getEntry()` to locate entries without decrypting the whole file.
|
|
130
155
|
*/
|
|
131
156
|
saveToFileStreaming(outputPath: string, passcode: string): Promise<void>;
|
|
157
|
+
/**
|
|
158
|
+
* Computes the decompressed byte offset of each entry within a binary plaintext buffer.
|
|
159
|
+
* The offset points to the start of that entry's nameLen byte.
|
|
160
|
+
*/
|
|
161
|
+
private static buildOffsetIndex;
|
|
162
|
+
/**
|
|
163
|
+
* Writes a `.spdi` index sidecar file for fast on-demand entry lookup.
|
|
164
|
+
* Format:
|
|
165
|
+
* [4B magic "SPDI"][4B version][8B entryCount][32B HMAC-SHA3-256 of body]
|
|
166
|
+
* for each entry: [1B nameLen][name bytes][8B LE uint64 decompressedOffset]
|
|
167
|
+
*/
|
|
168
|
+
private static writeIndexFile;
|
|
169
|
+
/**
|
|
170
|
+
* Reads and validates a `.spdi` index sidecar.
|
|
171
|
+
* Returns null if the file doesn't exist or the HMAC fails (falls back to scan).
|
|
172
|
+
*/
|
|
173
|
+
private static readIndexFile;
|
|
132
174
|
saveData(passcode?: string): Promise<string>;
|
|
133
175
|
/**
|
|
134
176
|
* Splits the payload into base64 chunks for chunked internet transfer.
|
|
@@ -170,9 +212,24 @@ declare class SPD {
|
|
|
170
212
|
* });
|
|
171
213
|
*/
|
|
172
214
|
static extractFromFileStreaming(filePath: string, passcode: string, tmpDir: string, callback: (name: string, value: unknown) => Promise<void> | void): Promise<void>;
|
|
215
|
+
/**
|
|
216
|
+
* On-demand disk lookup — decrypts and returns a single named entry from a
|
|
217
|
+
* binary `.spd` file (written by `saveToFileStreaming`) without loading the
|
|
218
|
+
* whole file into RAM.
|
|
219
|
+
*
|
|
220
|
+
* Uses a `.spdi` index sidecar (written alongside by `saveToFileStreaming`)
|
|
221
|
+
* for fast offset lookup when present. Falls back to a sequential scan if
|
|
222
|
+
* the sidecar is missing or its HMAC fails.
|
|
223
|
+
*
|
|
224
|
+
* The full plaintext MAC is always verified before any entry is decrypted —
|
|
225
|
+
* unauthenticated reads are never returned.
|
|
226
|
+
*
|
|
227
|
+
* RAM usage is bounded to ~one entry's worth of bytes at any time.
|
|
228
|
+
*/
|
|
229
|
+
static getEntry(filePath: string, passcode: string, name: string): Promise<SPDGetEntryResult>;
|
|
173
230
|
static loadFromString(data: string, passcode: string): Promise<SPD>;
|
|
174
231
|
static loadFromChunks(chunks: string[], passcode: string): Promise<SPD>;
|
|
175
|
-
static derivePBK(passcode: string, salt: Uint8Array, memory?: number, time?: number): Promise<PBKResult>;
|
|
232
|
+
static derivePBK(passcode: string, salt: Uint8Array, memory?: number, time?: number, hashLen?: number): Promise<PBKResult>;
|
|
176
233
|
static decryptSalt(encryptedSalt: number[], saltNonce: number[], wrapSalt: number[], passcode: string, memory?: number, time?: number): Promise<Uint8Array>;
|
|
177
234
|
static encryptSalt(salt: Uint8Array, passcode: string): Promise<EncryptedSaltResult>;
|
|
178
235
|
static toBase64(data: Uint8Array | Buffer): string;
|
|
@@ -265,4 +322,59 @@ declare class SPDVault {
|
|
|
265
322
|
destroy(): void;
|
|
266
323
|
}
|
|
267
324
|
|
|
268
|
-
|
|
325
|
+
/**
|
|
326
|
+
* SPDWriter — streaming, disk-backed binary SPD writer.
|
|
327
|
+
*
|
|
328
|
+
* Writes entries one at a time to disk as they are encrypted, so the full
|
|
329
|
+
* plaintext never exists in RAM simultaneously. Works on any device regardless
|
|
330
|
+
* of available memory.
|
|
331
|
+
*
|
|
332
|
+
* Usage:
|
|
333
|
+
* const writer = new SPDWriter('./output.spd', 'MyStr0ng!Passphrase#2024');
|
|
334
|
+
* await writer.init();
|
|
335
|
+
* await writer.addEntry('username', 'alice');
|
|
336
|
+
* await writer.addEntry('config', { theme: 'dark' });
|
|
337
|
+
* await writer.finalize();
|
|
338
|
+
*
|
|
339
|
+
* After finalize(), a `.spdi` index sidecar is written alongside the output
|
|
340
|
+
* file so that `SPD.getEntry()` can locate entries without a full scan.
|
|
341
|
+
*/
|
|
342
|
+
|
|
343
|
+
declare class SPDWriter {
|
|
344
|
+
private outputPath;
|
|
345
|
+
private passcode;
|
|
346
|
+
private opts;
|
|
347
|
+
private aeadKey?;
|
|
348
|
+
private macKey?;
|
|
349
|
+
private salt?;
|
|
350
|
+
private deflate?;
|
|
351
|
+
private outStream?;
|
|
352
|
+
private hmac?;
|
|
353
|
+
private plaintextOffset;
|
|
354
|
+
private entryCount;
|
|
355
|
+
private indexEntries;
|
|
356
|
+
private finalized;
|
|
357
|
+
private initialized;
|
|
358
|
+
constructor(outputPath: string, passcode: string, opts?: SPDWriterOptions);
|
|
359
|
+
/**
|
|
360
|
+
* Derives keys, opens the output file, and writes the meta block.
|
|
361
|
+
* Must be called before addEntry().
|
|
362
|
+
*/
|
|
363
|
+
init(): Promise<void>;
|
|
364
|
+
/**
|
|
365
|
+
* Encrypts one entry and streams it to disk.
|
|
366
|
+
*/
|
|
367
|
+
addEntry(name: string, value: unknown): Promise<void>;
|
|
368
|
+
/**
|
|
369
|
+
* Flushes the deflate stream, computes the HMAC, patches the file header,
|
|
370
|
+
* and writes the `.spdi` index sidecar.
|
|
371
|
+
*/
|
|
372
|
+
finalize(): Promise<void>;
|
|
373
|
+
/** Zero keys and remove the partial output file if finalize() was never called. */
|
|
374
|
+
destroy(): void;
|
|
375
|
+
/** Write bytes to the deflate stream and update the rolling HMAC + offset. */
|
|
376
|
+
private writeToPlaintext;
|
|
377
|
+
private writeIndexSidecar;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
export { ARGON2_MEMORY_HIGH, ARGON2_TIME_HIGH, type DataInput, type EncryptedDataEntry, type EncryptedSaltResult, type HashAlgorithm, type PBKResult, type PQCKey, type PQCKeyResult, SPD, type SPDChunkManifest, type SPDGetEntryResult, type SPDIndexEntry, SPDLegacy, type SPDLegacyPayload, type SPDPayload, SPDVault, SPDWriter, type SPDWriterOptions, SPDLegacy as SPD_LEG, SPDVault as SPD_Vault, type SerializedDataEntry, type SerializedWrappedPayload, type SupportedDataType, type SupportedValue, type TypedArray, type WrappedPayload };
|