@substrate-system/crypto-stream 0.0.35 → 0.1.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/README.md CHANGED
@@ -22,6 +22,7 @@ This uses the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/
22
22
  - [Fork](#fork)
23
23
  - [Example](#example)
24
24
  * [Example With Blobs](#example-with-blobs)
25
+ - [Seek](#seek)
25
26
  - [API](#api)
26
27
  * [`new Keychain([key, [salt]])`](#new-keychainkey-salt)
27
28
  * [`keychain.key`](#keychainkey)
@@ -32,7 +33,10 @@ This uses the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/
32
33
  * [`keychain.authTokenB64()`](#keychainauthtokenb64)
33
34
  * [`keychain.authHeader()`](#keychainauthheader)
34
35
  * [`keychain.setAuthToken(authToken)`](#keychainsetauthtokenauthtoken)
35
- * [`keychain.encryptStream(stream)`](#keychainencryptstreamstream)
36
+ * [`keychain.encryptStream(stream[, opts])`](#keychainencryptstreamstream-opts)
37
+ * [`keychain.contentDigest(content)`](#keychaincontentdigestcontent)
38
+ * [`keychain.header(opts)`](#keychainheaderopts)
39
+ * [`keychain.encryptRecord(seq, plaintext, opts)`](#keychainencryptrecordseq-plaintext-opts)
36
40
  * [`keychain.decryptStream(encryptedStream)`](#keychaindecryptstreamencryptedstream)
37
41
  * [`keychain.decryptStreamRange(offset, length, totalEncryptedLength)`](#keychaindecryptstreamrangeoffset-length-totalencryptedlength)
38
42
  * [`keychain.encryptMeta(meta)`](#keychainencryptmetameta)
@@ -41,6 +45,9 @@ This uses the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/
41
45
  * [`keychain.decryptBytes(bytes)`](#keychaindecryptbytesbytes)
42
46
  * [`plaintextSize(encryptedSize)`](#plaintextsizeencryptedsize)
43
47
  * [`encryptedSize(plaintextSize)`](#encryptedsizeplaintextsize)
48
+ - [Reproducible & record-addressable encryption](#reproducible--record-addressable-encryption)
49
+ * [Two-pass flow: hash, then encrypt](#two-pass-flow-hash-then-encrypt)
50
+ * [Low-level ECE building blocks](#low-level-ece-building-blocks)
44
51
  - [credits](#credits)
45
52
 
46
53
  <!-- tocstop -->
@@ -55,7 +62,10 @@ npm i -S @substrate-system/crypto-stream
55
62
 
56
63
  ## Fork
57
64
 
58
- This is a fork of [SocketDev/wormhole-crypto](https://github.com/SocketDev/wormhole-crypto). Thanks [@SocketDev](https://github.com/SocketDev) team for working in open source.
65
+ This is a fork of
66
+ [SocketDev/wormhole-crypto](https://github.com/SocketDev/wormhole-crypto).
67
+ Thanks [@SocketDev](https://github.com/SocketDev) team for working in the
68
+ world of open source.
59
69
 
60
70
  ## Example
61
71
 
@@ -100,6 +110,65 @@ function Component () {
100
110
  }
101
111
  ```
102
112
 
113
+ ## Seek
114
+
115
+ `crypto-stream` can seek on both sides of the cipher.
116
+
117
+ Reads use
118
+ [`decryptStreamRange`](#keychaindecryptstreamrangeoffset-length-totalencryptedlength),
119
+ which decrypts an arbitrary byte range without reading the whole
120
+ ciphertext.
121
+
122
+ Writes use *reproducible, record-addressable* encryption. The same plaintext
123
+ always encrypts to identical bytes, and you can regenerate any single record
124
+ on demand without re-encrypting the rest. That is what lets a peer seed a
125
+ large file (for example, over WebRTC) without buffering the whole ciphertext.
126
+ Hash the content once, then hand out individual records as they are requested.
127
+
128
+ ```js
129
+ import { Keychain } from '@substrate-system/crypto-stream'
130
+ import {
131
+ recordPlaintextSize,
132
+ recordCount
133
+ } from '@substrate-system/crypto-stream/src/ece'
134
+
135
+ const keychain = new Keychain()
136
+ const data = new TextEncoder().encode('the quick brown fox')
137
+ const rs = 1024 // record size; transport chunks line up with records
138
+
139
+ // 1. Hash pass. The salt is derived from this digest, so it is bound
140
+ // to exactly this content (no AES-GCM nonce reuse).
141
+ const digest = await keychain.contentDigest(data)
142
+
143
+ // 2. Reproducible whole-stream encrypt. Re-encrypting `data` with the
144
+ // same digest yields byte-identical output.
145
+ const encrypted = await keychain.encryptStream(new Response(data).body, {
146
+ contentDigest: digest,
147
+ recordSize: rs
148
+ })
149
+
150
+ // 3. Record-addressable: rebuild any single record on demand. The full
151
+ // ciphertext is `header || rec0 || rec1 || ... || recLast`.
152
+ const head = await keychain.header({ contentDigest: digest, recordSize: rs })
153
+
154
+ const max = recordPlaintextSize(rs) // plaintext bytes per record
155
+ const count = recordCount(data.length, rs) // number of data records
156
+
157
+ const i = 0
158
+ const slice = data.subarray(i * max, (i + 1) * max)
159
+ const record = await keychain.encryptRecord(i, slice, {
160
+ isLast: i === count - 1,
161
+ contentDigest: digest,
162
+ recordSize: rs
163
+ })
164
+ // `head || record` equals the first record of `encrypted`, byte for byte.
165
+ ```
166
+
167
+ See
168
+ [Reproducible & record-addressable encryption](#reproducible--record-addressable-encryption)
169
+ for the safety model (why the salt is derived from the content) and the
170
+ low-level building blocks.
171
+
103
172
  ## API
104
173
 
105
174
  ### `new Keychain([key, [salt]])`
@@ -223,10 +292,13 @@ The authentication token. This should be 16 bytes in length. If a `string` is
223
292
  given, then it should be a base64-encoded string. If this argument is `null`,
224
293
  then an authentication token will be automatically generated.
225
294
 
226
- ### `keychain.encryptStream(stream)`
295
+ ### `keychain.encryptStream(stream[, opts])`
227
296
 
228
297
  ```ts
229
- encryptStream (stream:ReadableStream):Promise<ReadableStream>
298
+ encryptStream (
299
+ stream:ReadableStream,
300
+ opts?:{ contentDigest?, recordSize? }
301
+ ):Promise<ReadableStream>
230
302
  ```
231
303
 
232
304
  Type: `Function`
@@ -237,12 +309,157 @@ Returns a `Promise` that resolves to a `ReadableStream` encryption stream that
237
309
  consumes the data in `stream` and returns an encrypted version. Data is
238
310
  encrypted with [Encrypted Content-Encoding for HTTP (RFC 8188)](https://tools.ietf.org/html/rfc8188).
239
311
 
312
+ If `opts.contentDigest` is provided, the salt is derived from the digest,
313
+ making the output reproducible — the same plaintext always produces
314
+ identical ciphertext. Without options, a fresh random salt is used
315
+ (default behavior; not reproducible).
316
+
240
317
  #### `stream`
241
318
 
242
319
  Type: `ReadableStream`
243
320
 
244
321
  A WHATWG readable stream used as a data source for the encrypted stream.
245
322
 
323
+ #### `opts`
324
+
325
+ Type: `{ contentDigest?, recordSize? }`
326
+
327
+ Optional encryption options.
328
+
329
+ ##### `contentDigest`
330
+
331
+ Type: `Uint8Array`
332
+
333
+ SHA-256 digest of the plaintext (from `keychain.contentDigest()`).
334
+ When provided, enables reproducible encryption by deriving the salt
335
+ from the digest internally.
336
+
337
+ ##### `recordSize`
338
+
339
+ Type: `number`
340
+
341
+ ECE record size in bytes (default `RECORD_SIZE` = 65536). Record size
342
+ affects output size and encryption granularity.
343
+
344
+ ### `keychain.contentDigest(content)`
345
+
346
+ ```ts
347
+ contentDigest (
348
+ content:ReadableStream<Uint8Array>|Uint8Array|Blob
349
+ ):Promise<Uint8Array>
350
+ ```
351
+
352
+ Type: `Function`
353
+
354
+ Returns: `Promise<Uint8Array>`
355
+
356
+ Returns a 32-byte SHA-256 digest of the plaintext. Use this digest as
357
+ the input to `encryptStream`, `header`, and `encryptRecord` to enable
358
+ reproducible encryption. Accepts a stream, byte array, or Blob; streams
359
+ and Blobs are drained into memory before hashing.
360
+
361
+ #### `content`
362
+
363
+ Type: `ReadableStream<Uint8Array> | Uint8Array | Blob`
364
+
365
+ The plaintext to hash.
366
+
367
+ ### `keychain.header(opts)`
368
+
369
+ ```ts
370
+ header (opts:{ contentDigest, recordSize? }):Promise<Uint8Array>
371
+ ```
372
+
373
+ Type: `Function`
374
+
375
+ Returns: `Promise<Uint8Array>`
376
+
377
+ Returns the 21-byte ECE header for content identified by the digest.
378
+ The salt is derived internally from the content digest, so this never
379
+ exposes a raw salt. The header is byte-identical to the header that
380
+ `encryptStream` with the same options emits.
381
+
382
+ #### `opts`
383
+
384
+ Type: `{ contentDigest, recordSize? }`
385
+
386
+ Required options.
387
+
388
+ ##### `contentDigest`
389
+
390
+ Type: `Uint8Array`
391
+
392
+ SHA-256 digest of the plaintext (from `keychain.contentDigest()`).
393
+
394
+ ##### `recordSize`
395
+
396
+ Type: `number`
397
+
398
+ ECE record size in bytes (default `RECORD_SIZE` = 65536).
399
+
400
+ ### `keychain.encryptRecord(seq, plaintext, opts)`
401
+
402
+ ```ts
403
+ encryptRecord (
404
+ seq:number,
405
+ plaintext:Uint8Array,
406
+ opts:{
407
+ isLast:boolean,
408
+ contentDigest:Uint8Array,
409
+ recordSize?:number
410
+ }
411
+ ):Promise<Uint8Array>
412
+ ```
413
+
414
+ Type: `Function`
415
+
416
+ Returns: `Promise<Uint8Array>`
417
+
418
+ Encrypts a single ECE record by index. The result is byte-identical to
419
+ record `seq` of `encryptStream` with the same content and options. The
420
+ salt is derived from the content digest internally.
421
+
422
+ Non-final records must be exactly `recordPlaintextSize(recordSize)` bytes;
423
+ the final record must be less than or equal to that. The low-level ECE
424
+ functions throw if violated.
425
+
426
+ #### `seq`
427
+
428
+ Type: `number`
429
+
430
+ Zero-based record index (0, 1, 2, ...).
431
+
432
+ #### `plaintext`
433
+
434
+ Type: `Uint8Array`
435
+
436
+ The record's plaintext data.
437
+
438
+ #### `opts`
439
+
440
+ Type: `{ isLast, contentDigest, recordSize? }`
441
+
442
+ Required options.
443
+
444
+ ##### `isLast`
445
+
446
+ Type: `boolean`
447
+
448
+ Whether this is the final record of the content.
449
+
450
+ ##### `contentDigest`
451
+
452
+ Type: `Uint8Array`
453
+
454
+ SHA-256 digest of the entire plaintext (from `keychain.contentDigest()`).
455
+
456
+ ##### `recordSize`
457
+
458
+ Type: `number`
459
+
460
+ ECE record size in bytes (default `RECORD_SIZE` = 65536). Must match
461
+ the record size used for the header and other records.
462
+
246
463
  ### `keychain.decryptStream(encryptedStream)`
247
464
 
248
465
  Type: `Function`
@@ -363,6 +580,66 @@ function encryptedSize (
363
580
 
364
581
  Given a plaintext size, return the corresponding encrypted size.
365
582
 
583
+ ## Reproducible & record-addressable encryption
584
+
585
+ By default, `encryptStream` uses a fresh random salt for each call.
586
+ This provides strong privacy (identical plaintexts don't leak through
587
+ repeated ciphertext), but the same input encrypted twice produces
588
+ different output.
589
+
590
+ For use cases like deduplication and content-addressed storage, you
591
+ need reproducible encryption: the same plaintext always produces
592
+ identical ciphertext. This is safe only if the salt is bound to the
593
+ plaintext, preventing a single salt from encrypting two different
594
+ contents (which would break AES-GCM).
595
+
596
+ The Keychain API enforces this binding automatically. The salt is
597
+ never chosen by the caller; it's derived from a content digest
598
+ (SHA-256 hash of the plaintext) via HKDF. This guarantees: a fixed
599
+ salt pairs with exactly one plaintext.
600
+
601
+ ### Two-pass flow: hash, then encrypt
602
+
603
+ To encrypt reproducibly, first compute the content digest, then
604
+ pass it to the encrypt functions:
605
+
606
+ ```js
607
+ // 1. Hash pass
608
+ const digest = await keychain.contentDigest(file.stream())
609
+
610
+ // 2. Encrypt pass — reproducible: same input -> identical ciphertext
611
+ const encrypted = await keychain.encryptStream(file.stream(), {
612
+ contentDigest: digest,
613
+ recordSize: rs
614
+ })
615
+
616
+ // On demand: regenerate record i byte-identically
617
+ const rec = await keychain.encryptRecord(i, sliceI, {
618
+ isLast,
619
+ contentDigest: digest,
620
+ recordSize: rs
621
+ })
622
+ // Full ciphertext = header(21) || rec0 || rec1 || ... || recLast
623
+ const head = await keychain.header({
624
+ contentDigest: digest,
625
+ recordSize: rs
626
+ })
627
+ ```
628
+
629
+ Note that `encryptStream` with no options keeps the original random-salt
630
+ behavior and is a single pass.
631
+
632
+ ### Low-level ECE building blocks
633
+
634
+ The package exports low-level ECE functions at
635
+ `@substrate-system/crypto-stream/src/ece`. These include `RECORD_SIZE`,
636
+ `HEADER_LENGTH`, `recordPlaintextSize`, `recordCount`, `header`,
637
+ `deriveContentSalt`, and `encryptRecord`. They take a raw salt directly
638
+ and are footgun-prone: passing the same raw salt with two different
639
+ plaintexts breaks AES-GCM (nonce-reuse catastrophe). Prefer the
640
+ Keychain API, which derives the salt from the content digest and is
641
+ nonce-reuse-safe by construction.
642
+
366
643
  ## credits
367
644
 
368
645
  Thank you
package/dist/ece.cjs CHANGED
@@ -19,13 +19,20 @@ var __copyProps = (to, from, except, desc) => {
19
19
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
20
  var ece_exports = {};
21
21
  __export(ece_exports, {
22
+ HEADER_LENGTH: () => HEADER_LENGTH,
22
23
  KEY_LENGTH: () => KEY_LENGTH,
24
+ RECORD_SIZE: () => RECORD_SIZE,
23
25
  TAG_LENGTH: () => TAG_LENGTH,
24
26
  decryptStream: () => decryptStream,
25
27
  decryptStreamRange: () => decryptStreamRange,
28
+ deriveContentSalt: () => deriveContentSalt,
29
+ encryptRecord: () => encryptRecord,
26
30
  encryptStream: () => encryptStream,
27
31
  encryptedSize: () => encryptedSize,
28
- plaintextSize: () => plaintextSize
32
+ header: () => header,
33
+ plaintextSize: () => plaintextSize,
34
+ recordCount: () => recordCount,
35
+ recordPlaintextSize: () => recordPlaintextSize
29
36
  });
30
37
  module.exports = __toCommonJS(ece_exports);
31
38
  var import_concat_streams = require("./concat-streams.js");
@@ -42,6 +49,7 @@ const NONCE_LENGTH = 12;
42
49
  const RECORD_SIZE = 64 * 1024;
43
50
  const HEADER_LENGTH = KEY_LENGTH + 4 + 1;
44
51
  const encoder = new TextEncoder();
52
+ const SALT_INFO = encoder.encode("Content-Encoding: salt\0");
45
53
  class ECETransformer {
46
54
  static {
47
55
  __name(this, "ECETransformer");
@@ -151,25 +159,21 @@ class ECETransformer {
151
159
  }
152
160
  createHeader() {
153
161
  if (!this.salt) throw new Error("Not salt");
154
- const header = new Uint8Array(HEADER_LENGTH);
155
- header.set(this.salt);
156
- const dv = new DataView(header.buffer, header.byteOffset, header.byteLength);
157
- dv.setUint32(KEY_LENGTH, this.rs);
158
- return header;
162
+ return header(this.salt, this.rs);
159
163
  }
160
164
  readHeader(buffer) {
161
165
  if (buffer.byteLength !== HEADER_LENGTH) {
162
166
  throw new Error("chunk is not expected header length");
163
167
  }
164
- const header = { salt: null, rs: null };
168
+ const header2 = { salt: null, rs: null };
165
169
  const dv = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
166
- header.salt = buffer.slice(0, KEY_LENGTH);
167
- header.rs = dv.getUint32(KEY_LENGTH);
170
+ header2.salt = buffer.slice(0, KEY_LENGTH);
171
+ header2.rs = dv.getUint32(KEY_LENGTH);
168
172
  const idlen = dv.getUint8(KEY_LENGTH + 4);
169
173
  if (idlen !== 0) {
170
174
  throw new Error("Implementation does not support non-zero idlen");
171
175
  }
172
- return header;
176
+ return header2;
173
177
  }
174
178
  async encryptRecord(record, seq, isLast) {
175
179
  const nonce = this.generateNonce(seq);
@@ -218,14 +222,14 @@ class ECETransformer {
218
222
  } else {
219
223
  if (this.seq === -1) {
220
224
  if (!this.prevChunk) throw new Error("not this.prevChunk");
221
- const header = this.readHeader(this.prevChunk);
222
- this.salt = (0, import_util.asBufferSource)(header.salt);
223
- if (this.rs !== null && this.rs !== header.rs) {
225
+ const header2 = this.readHeader(this.prevChunk);
226
+ this.salt = (0, import_util.asBufferSource)(header2.salt);
227
+ if (this.rs !== null && this.rs !== header2.rs) {
224
228
  throw new Error(
225
229
  "Record size declared in constructor does not match record size in encrypted stream"
226
230
  );
227
231
  }
228
- this.rs = header.rs;
232
+ this.rs = header2.rs;
229
233
  this.key = await this.generateKey();
230
234
  this.nonceBase = await this.generateNonceBase();
231
235
  const startSeq = this.seekOpts.startSeq;
@@ -287,6 +291,75 @@ function plaintextSize(encryptedSize2, rs = RECORD_SIZE) {
287
291
  return encryptedRecordsSize - chunkMetaLength * Math.ceil(encryptedRecordsSize / rs);
288
292
  }
289
293
  __name(plaintextSize, "plaintextSize");
294
+ function recordPlaintextSize(rs = RECORD_SIZE) {
295
+ if (!Number.isInteger(rs)) {
296
+ throw new TypeError("rs");
297
+ }
298
+ return rs - TAG_LENGTH - 1;
299
+ }
300
+ __name(recordPlaintextSize, "recordPlaintextSize");
301
+ function recordCount(plaintextSize2, rs = RECORD_SIZE) {
302
+ if (!Number.isInteger(plaintextSize2)) {
303
+ throw new TypeError("plaintextSize");
304
+ }
305
+ if (!Number.isInteger(rs)) {
306
+ throw new TypeError("rs");
307
+ }
308
+ return Math.ceil(plaintextSize2 / recordPlaintextSize(rs));
309
+ }
310
+ __name(recordCount, "recordCount");
311
+ function header(salt, rs = RECORD_SIZE) {
312
+ if (salt.byteLength !== KEY_LENGTH) {
313
+ throw new Error("Invalid salt length");
314
+ }
315
+ if (!Number.isInteger(rs)) {
316
+ throw new TypeError("rs");
317
+ }
318
+ const buf = new Uint8Array(HEADER_LENGTH);
319
+ buf.set(salt);
320
+ const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
321
+ dv.setUint32(KEY_LENGTH, rs);
322
+ return buf;
323
+ }
324
+ __name(header, "header");
325
+ async function deriveContentSalt(secretKey, contentDigest) {
326
+ if (contentDigest.byteLength === 0) {
327
+ throw new Error("empty content digest");
328
+ }
329
+ const infoLen = SALT_INFO.byteLength + contentDigest.byteLength;
330
+ const info = new Uint8Array(infoLen);
331
+ info.set(SALT_INFO, 0);
332
+ info.set(contentDigest, SALT_INFO.byteLength);
333
+ const bits = await import_one_webcrypto.webcrypto.subtle.deriveBits(
334
+ {
335
+ name: "HKDF",
336
+ hash: "SHA-256",
337
+ salt: new Uint8Array(0),
338
+ info
339
+ },
340
+ secretKey,
341
+ KEY_LENGTH * 8
342
+ );
343
+ return new Uint8Array(bits);
344
+ }
345
+ __name(deriveContentSalt, "deriveContentSalt");
346
+ async function encryptRecord(secretKey, seq, plaintext, isLast, salt, rs = RECORD_SIZE) {
347
+ const transformer = new ECETransformer(MODE_ENCRYPT, secretKey, rs, salt);
348
+ const max = recordPlaintextSize(rs);
349
+ if (isLast) {
350
+ if (plaintext.byteLength > max) {
351
+ throw new Error("final record exceeds recordPlaintextSize");
352
+ }
353
+ } else {
354
+ if (plaintext.byteLength !== max) {
355
+ throw new Error("non-final record must equal recordPlaintextSize");
356
+ }
357
+ }
358
+ transformer.key = await transformer.generateKey();
359
+ transformer.nonceBase = await transformer.generateNonceBase();
360
+ return transformer.encryptRecord(plaintext, seq, isLast);
361
+ }
362
+ __name(encryptRecord, "encryptRecord");
290
363
  function encryptStream(input, secretKey, rs = RECORD_SIZE, salt = (0, import_util.generateSalt)(KEY_LENGTH)) {
291
364
  const stream = (0, import_transform_stream.transformStream)(
292
365
  input,
package/dist/keychain.cjs CHANGED
@@ -162,17 +162,114 @@ class Keychain {
162
162
  setAuthToken(authToken) {
163
163
  this.authTokenPromise = Promise.resolve(decodeBits(authToken));
164
164
  }
165
+ /**
166
+ * SHA-256 digest of the plaintext, used as the input to content-bound
167
+ * salt derivation. Accepts a stream, a byte array, or a Blob;
168
+ * equivalent content yields the same digest.
169
+ *
170
+ * Pass the result to `encryptStream`/`header`/`encryptRecord` as
171
+ * `contentDigest`. The salt is derived from this digest internally,
172
+ * so the Keychain API never exposes a raw salt — a fixed salt can
173
+ * never pair with two different plaintexts.
174
+ *
175
+ * NOTE: WebCrypto has no incremental hash, so a stream/Blob is
176
+ * drained into memory before hashing.
177
+ *
178
+ * @param content Plaintext as a ReadableStream, Uint8Array, or Blob.
179
+ * @returns 32-byte SHA-256 digest.
180
+ */
181
+ async contentDigest(content) {
182
+ let bytes;
183
+ if (content instanceof Uint8Array) {
184
+ bytes = content;
185
+ } else if (content instanceof ReadableStream) {
186
+ bytes = new Uint8Array(await new Response(content).arrayBuffer());
187
+ } else if (typeof Blob !== "undefined" && content instanceof Blob) {
188
+ bytes = new Uint8Array(await content.arrayBuffer());
189
+ } else {
190
+ throw new TypeError(
191
+ "content must be a ReadableStream, Uint8Array, or Blob"
192
+ );
193
+ }
194
+ const digest = await import_one_webcrypto.webcrypto.subtle.digest(
195
+ "SHA-256",
196
+ (0, import_util.asBufferSource)(bytes)
197
+ );
198
+ return new Uint8Array(digest);
199
+ }
165
200
  /**
166
201
  * Take a stream, return an encrypted stream.
167
- * @param stream Input stream
168
- * @returns {Promise<ReadableStream>}
202
+ *
203
+ * With `opts.contentDigest`, the ECE salt is derived from the digest
204
+ * internally (`deriveContentSalt`), so two calls over identical input
205
+ * produce byte-identical ciphertext (reproducible encryption). With no
206
+ * opts, a fresh random salt is used (today's behavior).
207
+ *
208
+ * The salt is never accepted directly: because it is bound to the
209
+ * content digest, a fixed salt can never encrypt two different
210
+ * plaintexts (AES-GCM nonce-reuse is structurally unreachable from
211
+ * this API).
212
+ *
213
+ * @param stream Input plaintext stream.
214
+ * @param opts Optional `{ contentDigest?, recordSize? }`.
215
+ * @returns Encrypted stream.
169
216
  */
170
- async encryptStream(stream) {
217
+ async encryptStream(stream, opts) {
171
218
  if (!(stream instanceof ReadableStream)) {
172
219
  throw new TypeError("This is not a readable stream");
173
220
  }
174
221
  const mainKey = await this.mainKeyPromise;
175
- return (0, import_ece.encryptStream)(stream, mainKey);
222
+ const rs = opts?.recordSize ?? import_ece.RECORD_SIZE;
223
+ if (opts?.contentDigest) {
224
+ const salt = await (0, import_ece.deriveContentSalt)(mainKey, opts.contentDigest);
225
+ return (0, import_ece.encryptStream)(stream, mainKey, rs, salt);
226
+ }
227
+ return (0, import_ece.encryptStream)(stream, mainKey, rs);
228
+ }
229
+ /**
230
+ * Build the 21-byte ECE header for content identified by
231
+ * `contentDigest`. The salt is derived internally from the digest,
232
+ * so this never exposes a raw salt. The header is byte-identical to
233
+ * the header that `encryptStream({ contentDigest, recordSize })`
234
+ * emits for the same input.
235
+ *
236
+ * @param opts `{ contentDigest, recordSize? }`.
237
+ * @returns The 21-byte header.
238
+ */
239
+ async header(opts) {
240
+ const mainKey = await this.mainKeyPromise;
241
+ const salt = await (0, import_ece.deriveContentSalt)(mainKey, opts.contentDigest);
242
+ return (0, import_ece.header)(salt, opts.recordSize ?? import_ece.RECORD_SIZE);
243
+ }
244
+ /**
245
+ * Encrypt a single ECE record by index, byte-identical to record
246
+ * `seq` of `encryptStream({ contentDigest, recordSize })`. The salt
247
+ * is derived from `contentDigest` internally; no raw salt is
248
+ * accepted.
249
+ *
250
+ * Non-final records must be exactly `recordPlaintextSize(recordSize)`
251
+ * bytes; the final record must be `<=` that. The low-level function
252
+ * throws otherwise.
253
+ *
254
+ * @param seq Zero-based record index.
255
+ * @param plaintext The record's plaintext slice.
256
+ * @param opts `{ isLast, contentDigest, recordSize? }`.
257
+ * @returns The encrypted record bytes.
258
+ */
259
+ async encryptRecord(seq, plaintext, opts) {
260
+ const mainKey = await this.mainKeyPromise;
261
+ const salt = await (0, import_ece.deriveContentSalt)(
262
+ mainKey,
263
+ opts.contentDigest
264
+ );
265
+ return (0, import_ece.encryptRecord)(
266
+ mainKey,
267
+ seq,
268
+ plaintext,
269
+ opts.isLast,
270
+ salt,
271
+ opts.recordSize ?? import_ece.RECORD_SIZE
272
+ );
176
273
  }
177
274
  /**
178
275
  * Encrypt and return some data; don't stream.
package/dist/src/ece.d.ts CHANGED
@@ -4,6 +4,8 @@
4
4
  */
5
5
  export declare const KEY_LENGTH = 16;
6
6
  export declare const TAG_LENGTH = 16;
7
+ export declare const RECORD_SIZE: number;
8
+ export declare const HEADER_LENGTH: number;
7
9
  /**
8
10
  * Given a plaintext size, return the corresponding encrypted size.
9
11
  *
@@ -18,6 +20,80 @@ export declare function encryptedSize(plaintextSize: number, rs?: number): numbe
18
20
  * rs: int containing record size, optional
19
21
  */
20
22
  export declare function plaintextSize(encryptedSize: number, rs?: number): number;
23
+ /**
24
+ * Plaintext bytes that fit in one ECE record for the given record size.
25
+ * Equals `rs - TAG_LENGTH - 1` (the 16-byte AES-GCM tag plus the 1-byte
26
+ * padding delimiter).
27
+ *
28
+ * @param rs Record size in bytes (default RECORD_SIZE).
29
+ * @returns Plaintext bytes per record.
30
+ */
31
+ export declare function recordPlaintextSize(rs?: number): number;
32
+ /**
33
+ * Number of ECE data records needed to hold `plaintextSize` bytes. Returns 0
34
+ * for empty input — an empty stream encrypts to a header with no
35
+ * data records.
36
+ *
37
+ * @param plaintextSize Total plaintext length in bytes.
38
+ * @param rs Record size in bytes (default RECORD_SIZE).
39
+ * @returns Record count (0 when plaintextSize is 0).
40
+ */
41
+ export declare function recordCount(plaintextSize: number, rs?: number): number;
42
+ /**
43
+ * Build the canonical 21-byte ECE header:
44
+ * `salt(16) || recordSize(uint32 BE) || idlen(0)`.
45
+ *
46
+ * This is the single source of truth for the header; the streaming encoder
47
+ * delegates to it, so a standalone header is byte-identical to the stream's
48
+ * header.
49
+ *
50
+ * SAFETY: a fixed salt must never encrypt two different plaintexts under the
51
+ * same key (AES-GCM nonce reuse). Prefer deriving the salt from the content
52
+ * (see `deriveContentSalt`) over choosing it directly. This is a low-level
53
+ * building block; the Keychain API does not accept a raw salt.
54
+ *
55
+ * @param salt 16-byte content salt.
56
+ * @param rs Record size in bytes (default RECORD_SIZE).
57
+ * @returns The 21-byte header.
58
+ */
59
+ export declare function header(salt: Uint8Array<ArrayBuffer>, rs?: number): Uint8Array<ArrayBuffer>;
60
+ /**
61
+ * Derive a deterministic 16-byte content salt from the secret key and a
62
+ * content digest, via HKDF-SHA256 with info
63
+ * `"Content-Encoding: salt\0" || contentDigest`.
64
+ *
65
+ * Because the digest is collision-resistant over the plaintext, a salt is
66
+ * cryptographically bound to exactly one content — so a fixed salt can never
67
+ * pair with two different plaintexts. This is what makes reproducible
68
+ * encryption safe under AES-GCM (no nonce reuse across distinct plaintexts).
69
+ *
70
+ * @param secretKey HKDF CryptoKey (the main secret key).
71
+ * @param contentDigest Digest of the plaintext (e.g. 32-byte SHA-256).
72
+ * @returns 16-byte content salt.
73
+ */
74
+ export declare function deriveContentSalt(secretKey: CryptoKey, contentDigest: Uint8Array): Promise<Uint8Array<ArrayBuffer>>;
75
+ /**
76
+ * Encrypt a single ECE record in isolation, byte-identical to record `seq` of
77
+ * the corresponding `encryptStream` output. Drives an `ECETransformer` through
78
+ * its existing key/nonce/record methods, so no new crypto is introduced.
79
+ *
80
+ * Non-final records must be exactly `recordPlaintextSize(rs)` bytes; the final
81
+ * record must be `<= recordPlaintextSize(rs)` bytes.
82
+ *
83
+ * SAFETY: the same `(secretKey, salt)` must never encrypt two different
84
+ * plaintexts (AES-GCM nonce reuse). This low-level function takes a raw salt;
85
+ * derive it from the content via `deriveContentSalt`, or use the Keychain API,
86
+ * which never exposes a raw salt.
87
+ *
88
+ * @param secretKey HKDF CryptoKey (the main secret key).
89
+ * @param seq Zero-based record index.
90
+ * @param plaintext The record's plaintext slice.
91
+ * @param isLast Whether this is the final record.
92
+ * @param salt 16-byte content salt (same salt as the stream's header).
93
+ * @param rs Record size in bytes (default RECORD_SIZE).
94
+ * @returns The encrypted record bytes.
95
+ */
96
+ export declare function encryptRecord(secretKey: CryptoKey, seq: number, plaintext: Uint8Array, isLast: boolean, salt: Uint8Array<ArrayBuffer>, rs?: number): Promise<Uint8Array>;
21
97
  /**
22
98
  * Given a plaintext stream `input`, return an encrypted stream.
23
99
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ece.d.ts","sourceRoot":"","sources":["../../src/ece.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,UAAU,KAAK,CAAA;AAmS5B;;;;;GAKG;AACH,wBAAgB,aAAa,CACzB,aAAa,EAAC,MAAM,EACpB,EAAE,GAAC,MAAoB,GACzB,MAAM,CAcP;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CACzB,aAAa,EAAC,MAAM,EACpB,EAAE,GAAC,MAAoB,GACzB,MAAM,CAeP;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CACzB,KAAK,EAAC,cAAc,EACpB,SAAS,EAAC,SAAS,EACnB,EAAE,GAAC,MAAoB,EACvB,IAAI,GAAC,UAAU,CAAC,WAAW,CAA4B,GACzD,cAAc,CAUf;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CACzB,KAAK,EAAC,cAAc,EACpB,SAAS,EAAC,SAAS,EACnB,EAAE,SAAc,GAClB,cAAc,CAUf;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAC,SAAS,EACnB,MAAM,EAAC,MAAM,EACb,MAAM,EAAC,MAAM,EACb,oBAAoB,EAAC,MAAM,EAC3B,EAAE,GAAC,MAAoB,GACzB;IACE,MAAM,EAAC;QAAE,MAAM,EAAC,MAAM,CAAC;QAAC,MAAM,EAAC,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,OAAO,EAAC,CAAC,OAAO,EAAC,cAAc,EAAE,KAAG,cAAc,CAAA;CACrD,CAiEA"}
1
+ {"version":3,"file":"ece.d.ts","sourceRoot":"","sources":["../../src/ece.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,eAAO,MAAM,UAAU,KAAK,CAAA;AAC5B,eAAO,MAAM,UAAU,KAAK,CAAA;AAE5B,eAAO,MAAM,WAAW,QAAY,CAAA;AACpC,eAAO,MAAM,aAAa,QAAqB,CAAA;AA6R/C;;;;;GAKG;AACH,wBAAgB,aAAa,CACzB,aAAa,EAAC,MAAM,EACpB,EAAE,GAAC,MAAoB,GACzB,MAAM,CAcP;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CACzB,aAAa,EAAC,MAAM,EACpB,EAAE,GAAC,MAAoB,GACzB,MAAM,CAeP;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAE,EAAE,GAAC,MAAoB,GAAE,MAAM,CAKnE;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACvB,aAAa,EAAC,MAAM,EACpB,EAAE,GAAC,MAAoB,GACzB,MAAM,CAQP;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,MAAM,CAClB,IAAI,EAAC,UAAU,CAAC,WAAW,CAAC,EAC5B,EAAE,GAAC,MAAoB,GACzB,UAAU,CAAC,WAAW,CAAC,CAYxB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,iBAAiB,CACnC,SAAS,EAAC,SAAS,EACnB,aAAa,EAAC,UAAU,GAC1B,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC,CAsBjC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,aAAa,CAC/B,SAAS,EAAC,SAAS,EACnB,GAAG,EAAC,MAAM,EACV,SAAS,EAAC,UAAU,EACpB,MAAM,EAAC,OAAO,EACd,IAAI,EAAC,UAAU,CAAC,WAAW,CAAC,EAC5B,EAAE,GAAC,MAAoB,GACzB,OAAO,CAAC,UAAU,CAAC,CAmBpB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CACzB,KAAK,EAAC,cAAc,EACpB,SAAS,EAAC,SAAS,EACnB,EAAE,GAAC,MAAoB,EACvB,IAAI,GAAC,UAAU,CAAC,WAAW,CAA4B,GACzD,cAAc,CAUf;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CACzB,KAAK,EAAC,cAAc,EACpB,SAAS,EAAC,SAAS,EACnB,EAAE,SAAc,GAClB,cAAc,CAUf;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAC9B,SAAS,EAAC,SAAS,EACnB,MAAM,EAAC,MAAM,EACb,MAAM,EAAC,MAAM,EACb,oBAAoB,EAAC,MAAM,EAC3B,EAAE,GAAC,MAAoB,GACzB;IACE,MAAM,EAAC;QAAE,MAAM,EAAC,MAAM,CAAC;QAAC,MAAM,EAAC,MAAM,CAAA;KAAE,EAAE,CAAC;IAC1C,OAAO,EAAC,CAAC,OAAO,EAAC,cAAc,EAAE,KAAG,cAAc,CAAA;CACrD,CAiEA"}
package/dist/src/ece.js CHANGED
@@ -13,9 +13,10 @@ const MODE_DECRYPT = 'decrypt';
13
13
  export const KEY_LENGTH = 16;
14
14
  export const TAG_LENGTH = 16;
15
15
  const NONCE_LENGTH = 12;
16
- const RECORD_SIZE = 64 * 1024;
17
- const HEADER_LENGTH = KEY_LENGTH + 4 + 1; // salt + record size + idlen
16
+ export const RECORD_SIZE = 64 * 1024;
17
+ export const HEADER_LENGTH = KEY_LENGTH + 4 + 1; // salt + record size + idlen
18
18
  const encoder = new TextEncoder();
19
+ const SALT_INFO = encoder.encode('Content-Encoding: salt\0');
19
20
  class ECETransformer {
20
21
  mode;
21
22
  secretKey;
@@ -121,11 +122,7 @@ class ECETransformer {
121
122
  createHeader() {
122
123
  if (!this.salt)
123
124
  throw new Error('Not salt');
124
- const header = new Uint8Array(HEADER_LENGTH);
125
- header.set(this.salt);
126
- const dv = new DataView(header.buffer, header.byteOffset, header.byteLength);
127
- dv.setUint32(KEY_LENGTH, this.rs);
128
- return header;
125
+ return header(this.salt, this.rs);
129
126
  }
130
127
  readHeader(buffer) {
131
128
  if (buffer.byteLength !== HEADER_LENGTH) {
@@ -264,6 +261,137 @@ export function plaintextSize(encryptedSize, rs = RECORD_SIZE) {
264
261
  chunkMetaLength *
265
262
  Math.ceil(encryptedRecordsSize / rs));
266
263
  }
264
+ /**
265
+ * Plaintext bytes that fit in one ECE record for the given record size.
266
+ * Equals `rs - TAG_LENGTH - 1` (the 16-byte AES-GCM tag plus the 1-byte
267
+ * padding delimiter).
268
+ *
269
+ * @param rs Record size in bytes (default RECORD_SIZE).
270
+ * @returns Plaintext bytes per record.
271
+ */
272
+ export function recordPlaintextSize(rs = RECORD_SIZE) {
273
+ if (!Number.isInteger(rs)) {
274
+ throw new TypeError('rs');
275
+ }
276
+ return rs - TAG_LENGTH - 1;
277
+ }
278
+ /**
279
+ * Number of ECE data records needed to hold `plaintextSize` bytes. Returns 0
280
+ * for empty input — an empty stream encrypts to a header with no
281
+ * data records.
282
+ *
283
+ * @param plaintextSize Total plaintext length in bytes.
284
+ * @param rs Record size in bytes (default RECORD_SIZE).
285
+ * @returns Record count (0 when plaintextSize is 0).
286
+ */
287
+ export function recordCount(plaintextSize, rs = RECORD_SIZE) {
288
+ if (!Number.isInteger(plaintextSize)) {
289
+ throw new TypeError('plaintextSize');
290
+ }
291
+ if (!Number.isInteger(rs)) {
292
+ throw new TypeError('rs');
293
+ }
294
+ return Math.ceil(plaintextSize / recordPlaintextSize(rs));
295
+ }
296
+ /**
297
+ * Build the canonical 21-byte ECE header:
298
+ * `salt(16) || recordSize(uint32 BE) || idlen(0)`.
299
+ *
300
+ * This is the single source of truth for the header; the streaming encoder
301
+ * delegates to it, so a standalone header is byte-identical to the stream's
302
+ * header.
303
+ *
304
+ * SAFETY: a fixed salt must never encrypt two different plaintexts under the
305
+ * same key (AES-GCM nonce reuse). Prefer deriving the salt from the content
306
+ * (see `deriveContentSalt`) over choosing it directly. This is a low-level
307
+ * building block; the Keychain API does not accept a raw salt.
308
+ *
309
+ * @param salt 16-byte content salt.
310
+ * @param rs Record size in bytes (default RECORD_SIZE).
311
+ * @returns The 21-byte header.
312
+ */
313
+ export function header(salt, rs = RECORD_SIZE) {
314
+ if (salt.byteLength !== KEY_LENGTH) {
315
+ throw new Error('Invalid salt length');
316
+ }
317
+ if (!Number.isInteger(rs)) {
318
+ throw new TypeError('rs');
319
+ }
320
+ const buf = new Uint8Array(HEADER_LENGTH);
321
+ buf.set(salt);
322
+ const dv = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
323
+ dv.setUint32(KEY_LENGTH, rs);
324
+ return buf;
325
+ }
326
+ /**
327
+ * Derive a deterministic 16-byte content salt from the secret key and a
328
+ * content digest, via HKDF-SHA256 with info
329
+ * `"Content-Encoding: salt\0" || contentDigest`.
330
+ *
331
+ * Because the digest is collision-resistant over the plaintext, a salt is
332
+ * cryptographically bound to exactly one content — so a fixed salt can never
333
+ * pair with two different plaintexts. This is what makes reproducible
334
+ * encryption safe under AES-GCM (no nonce reuse across distinct plaintexts).
335
+ *
336
+ * @param secretKey HKDF CryptoKey (the main secret key).
337
+ * @param contentDigest Digest of the plaintext (e.g. 32-byte SHA-256).
338
+ * @returns 16-byte content salt.
339
+ */
340
+ export async function deriveContentSalt(secretKey, contentDigest) {
341
+ if (contentDigest.byteLength === 0) {
342
+ throw new Error('empty content digest');
343
+ }
344
+ const infoLen = SALT_INFO.byteLength + contentDigest.byteLength;
345
+ const info = new Uint8Array(infoLen);
346
+ info.set(SALT_INFO, 0);
347
+ info.set(contentDigest, SALT_INFO.byteLength);
348
+ const bits = await webcrypto.subtle.deriveBits({
349
+ name: 'HKDF',
350
+ hash: 'SHA-256',
351
+ salt: new Uint8Array(0),
352
+ info
353
+ }, secretKey, KEY_LENGTH * 8);
354
+ return new Uint8Array(bits);
355
+ }
356
+ /**
357
+ * Encrypt a single ECE record in isolation, byte-identical to record `seq` of
358
+ * the corresponding `encryptStream` output. Drives an `ECETransformer` through
359
+ * its existing key/nonce/record methods, so no new crypto is introduced.
360
+ *
361
+ * Non-final records must be exactly `recordPlaintextSize(rs)` bytes; the final
362
+ * record must be `<= recordPlaintextSize(rs)` bytes.
363
+ *
364
+ * SAFETY: the same `(secretKey, salt)` must never encrypt two different
365
+ * plaintexts (AES-GCM nonce reuse). This low-level function takes a raw salt;
366
+ * derive it from the content via `deriveContentSalt`, or use the Keychain API,
367
+ * which never exposes a raw salt.
368
+ *
369
+ * @param secretKey HKDF CryptoKey (the main secret key).
370
+ * @param seq Zero-based record index.
371
+ * @param plaintext The record's plaintext slice.
372
+ * @param isLast Whether this is the final record.
373
+ * @param salt 16-byte content salt (same salt as the stream's header).
374
+ * @param rs Record size in bytes (default RECORD_SIZE).
375
+ * @returns The encrypted record bytes.
376
+ */
377
+ export async function encryptRecord(secretKey, seq, plaintext, isLast, salt, rs = RECORD_SIZE) {
378
+ // Validates the key and the salt length (throws 'Invalid salt length').
379
+ const transformer = new ECETransformer(MODE_ENCRYPT, secretKey, rs, salt);
380
+ const max = recordPlaintextSize(rs);
381
+ if (isLast) {
382
+ if (plaintext.byteLength > max) {
383
+ throw new Error('final record exceeds recordPlaintextSize');
384
+ }
385
+ }
386
+ else {
387
+ if (plaintext.byteLength !== max) {
388
+ throw new Error('non-final record must equal recordPlaintextSize');
389
+ }
390
+ }
391
+ transformer.key = await transformer.generateKey();
392
+ transformer.nonceBase = await transformer.generateNonceBase();
393
+ return transformer.encryptRecord(plaintext, seq, isLast);
394
+ }
267
395
  /**
268
396
  * Given a plaintext stream `input`, return an encrypted stream.
269
397
  *
@@ -1 +1 @@
1
- {"version":3,"file":"ece.js","sourceRoot":"","sources":["../../src/ece.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ece.js","sourceRoot":"","sources":["../../src/ece.ts"],"names":[],"mappings":"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"}
@@ -39,12 +39,78 @@ export declare class Keychain {
39
39
  * @param authToken The new token
40
40
  */
41
41
  setAuthToken(authToken?: string | Uint8Array): void;
42
+ /**
43
+ * SHA-256 digest of the plaintext, used as the input to content-bound
44
+ * salt derivation. Accepts a stream, a byte array, or a Blob;
45
+ * equivalent content yields the same digest.
46
+ *
47
+ * Pass the result to `encryptStream`/`header`/`encryptRecord` as
48
+ * `contentDigest`. The salt is derived from this digest internally,
49
+ * so the Keychain API never exposes a raw salt — a fixed salt can
50
+ * never pair with two different plaintexts.
51
+ *
52
+ * NOTE: WebCrypto has no incremental hash, so a stream/Blob is
53
+ * drained into memory before hashing.
54
+ *
55
+ * @param content Plaintext as a ReadableStream, Uint8Array, or Blob.
56
+ * @returns 32-byte SHA-256 digest.
57
+ */
58
+ contentDigest(content: ReadableStream<Uint8Array> | Uint8Array | Blob): Promise<Uint8Array<ArrayBuffer>>;
42
59
  /**
43
60
  * Take a stream, return an encrypted stream.
44
- * @param stream Input stream
45
- * @returns {Promise<ReadableStream>}
61
+ *
62
+ * With `opts.contentDigest`, the ECE salt is derived from the digest
63
+ * internally (`deriveContentSalt`), so two calls over identical input
64
+ * produce byte-identical ciphertext (reproducible encryption). With no
65
+ * opts, a fresh random salt is used (today's behavior).
66
+ *
67
+ * The salt is never accepted directly: because it is bound to the
68
+ * content digest, a fixed salt can never encrypt two different
69
+ * plaintexts (AES-GCM nonce-reuse is structurally unreachable from
70
+ * this API).
71
+ *
72
+ * @param stream Input plaintext stream.
73
+ * @param opts Optional `{ contentDigest?, recordSize? }`.
74
+ * @returns Encrypted stream.
46
75
  */
47
- encryptStream(stream: ReadableStream<Uint8Array>): Promise<ReadableStream<Uint8Array>>;
76
+ encryptStream(stream: ReadableStream<Uint8Array>, opts?: {
77
+ contentDigest?: Uint8Array;
78
+ recordSize?: number;
79
+ }): Promise<ReadableStream<Uint8Array>>;
80
+ /**
81
+ * Build the 21-byte ECE header for content identified by
82
+ * `contentDigest`. The salt is derived internally from the digest,
83
+ * so this never exposes a raw salt. The header is byte-identical to
84
+ * the header that `encryptStream({ contentDigest, recordSize })`
85
+ * emits for the same input.
86
+ *
87
+ * @param opts `{ contentDigest, recordSize? }`.
88
+ * @returns The 21-byte header.
89
+ */
90
+ header(opts: {
91
+ contentDigest: Uint8Array;
92
+ recordSize?: number;
93
+ }): Promise<Uint8Array<ArrayBuffer>>;
94
+ /**
95
+ * Encrypt a single ECE record by index, byte-identical to record
96
+ * `seq` of `encryptStream({ contentDigest, recordSize })`. The salt
97
+ * is derived from `contentDigest` internally; no raw salt is
98
+ * accepted.
99
+ *
100
+ * Non-final records must be exactly `recordPlaintextSize(recordSize)`
101
+ * bytes; the final record must be `<=` that. The low-level function
102
+ * throws otherwise.
103
+ *
104
+ * @param seq Zero-based record index.
105
+ * @param plaintext The record's plaintext slice.
106
+ * @param opts `{ isLast, contentDigest, recordSize? }`.
107
+ * @returns The encrypted record bytes.
108
+ */
109
+ encryptRecord(seq: number, plaintext: Uint8Array, opts: {
110
+ isLast: boolean;
111
+ contentDigest: Uint8Array;
112
+ recordSize?: number;
113
+ }): Promise<Uint8Array>;
48
114
  /**
49
115
  * Encrypt and return some data; don't stream.
50
116
  *
@@ -1 +1 @@
1
- {"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../../src/keychain.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAKvD,qBAAa,QAAQ;IACjB,GAAG,EAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IAC3B,IAAI,EAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IAC5B,cAAc,EAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACjC,cAAc,EAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACjC,gBAAgB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gBAEvB,GAAG,CAAC,EAAC,MAAM,GAAC,UAAU,EAAE,IAAI,CAAC,EAAC,MAAM,GAAC,UAAU;IA+C5D;;OAEG;WACU,UAAU,CAAE,SAAS,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM,GAAC,UAAU;IAwBjE,MAAM,CAAC,MAAM,CAAE,UAAU,EAAC,MAAM;IAIhC;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IAItC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAKrC;;;;OAIG;IACG,UAAU,CAAE,WAAW,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC;IAQtD;;;OAGG;IACH,YAAY,CAAE,SAAS,CAAC,EAAC,MAAM,GAAC,UAAU,GAAE,IAAI;IAIhD;;;;OAIG;IACG,aAAa,CACf,MAAM,EAAC,cAAc,CAAC,UAAU,CAAC,GACnC,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAQrC;;;;;;;;;;;OAWG;IACG,YAAY,CACd,KAAK,EAAC,WAAW,GAAC,UAAU,EAC5B,IAAI,CAAC,EAAC;QAAE,EAAE,CAAC,EAAC,UAAU,CAAC;QAAC,IAAI,CAAC,EAAC,MAAM,CAAA;KAAE,GACxC,OAAO,CAAC,UAAU,CAAC;IAcrB;;OAEG;IACG,YAAY,CACd,KAAK,EAAC,UAAU,GAClB,OAAO,CAAC,WAAW,CAAC;IAatB;;;;;;OAMG;IACG,WAAW,CAAE,SAAS,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,SAAS,CAAC;IAoBxD;;;;OAIG;IACG,aAAa,CACf,eAAe,EAAC,cAAc,CAAC,UAAU,CAAC,GAC5C,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAQrC;;;;;;;;;;OAUG;IACG,kBAAkB,CACpB,MAAM,EAAC,MAAM,EACb,MAAM,EAAC,MAAM,EACb,oBAAoB,EAAC,MAAM,GAC7B,OAAO,CAAC;QACN,MAAM,EAAC;YAAE,MAAM,EAAC,MAAM,CAAC;YAAC,MAAM,EAAC,MAAM,CAAA;SAAE,EAAE,CAAC;QAC1C,OAAO,EAAC,CAAC,OAAO,EAAC,cAAc,EAAE,KAAG,cAAc,CAAA;KACrD,CAAC;IAeI,WAAW,CAAE,IAAI,EAAC,UAAU,GAAE,OAAO,CAAC,UAAU,CAAC;IA2BjD,WAAW,CAAE,eAAe,EAAC,UAAU,GAAE,OAAO,CAAC,UAAU,CAAC;CAqBrE"}
1
+ {"version":3,"file":"keychain.d.ts","sourceRoot":"","sources":["../../src/keychain.ts"],"names":[],"mappings":"AAcA,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAKvD,qBAAa,QAAQ;IACjB,GAAG,EAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IAC3B,IAAI,EAAC,UAAU,CAAC,WAAW,CAAC,CAAA;IAC5B,cAAc,EAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACjC,cAAc,EAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACjC,gBAAgB,EAAC,OAAO,CAAC,UAAU,CAAC,CAAA;gBAEvB,GAAG,CAAC,EAAC,MAAM,GAAC,UAAU,EAAE,IAAI,CAAC,EAAC,MAAM,GAAC,UAAU;IA+C5D;;OAEG;WACU,UAAU,CAAE,SAAS,EAAC,MAAM,EAAE,IAAI,EAAC,MAAM,GAAC,UAAU;IAwBjE,MAAM,CAAC,MAAM,CAAE,UAAU,EAAC,MAAM;IAIhC;;OAEG;IACH,IAAI,MAAM,IAAI,MAAM,CAEnB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,UAAU,CAAC;IAItC;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC;IAKrC;;;;OAIG;IACG,UAAU,CAAE,WAAW,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,MAAM,CAAC;IAQtD;;;OAGG;IACH,YAAY,CAAE,SAAS,CAAC,EAAC,MAAM,GAAC,UAAU,GAAE,IAAI;IAIhD;;;;;;;;;;;;;;;OAeG;IACG,aAAa,CACf,OAAO,EAAC,cAAc,CAAC,UAAU,CAAC,GAAC,UAAU,GAAC,IAAI,GACpD,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAqBlC;;;;;;;;;;;;;;;;OAgBG;IACG,aAAa,CACf,MAAM,EAAC,cAAc,CAAC,UAAU,CAAC,EACjC,IAAI,CAAC,EAAC;QACF,aAAa,CAAC,EAAC,UAAU,CAAC;QAC1B,UAAU,CAAC,EAAC,MAAM,CAAA;KACrB,GACH,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAerC;;;;;;;;;OASG;IACG,MAAM,CACR,IAAI,EAAC;QAAC,aAAa,EAAC,UAAU,CAAC;QAAC,UAAU,CAAC,EAAC,MAAM,CAAA;KAAC,GACrD,OAAO,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;IAMlC;;;;;;;;;;;;;;OAcG;IACG,aAAa,CACf,GAAG,EAAC,MAAM,EACV,SAAS,EAAC,UAAU,EACpB,IAAI,EAAC;QACD,MAAM,EAAC,OAAO,CAAC;QACf,aAAa,EAAC,UAAU,CAAC;QACzB,UAAU,CAAC,EAAC,MAAM,CAAA;KACrB,GACH,OAAO,CAAC,UAAU,CAAC;IAgBrB;;;;;;;;;;;OAWG;IACG,YAAY,CACd,KAAK,EAAC,WAAW,GAAC,UAAU,EAC5B,IAAI,CAAC,EAAC;QAAE,EAAE,CAAC,EAAC,UAAU,CAAC;QAAC,IAAI,CAAC,EAAC,MAAM,CAAA;KAAE,GACxC,OAAO,CAAC,UAAU,CAAC;IAcrB;;OAEG;IACG,YAAY,CACd,KAAK,EAAC,UAAU,GAClB,OAAO,CAAC,WAAW,CAAC;IAatB;;;;;;OAMG;IACG,WAAW,CAAE,SAAS,CAAC,EAAC,MAAM,GAAE,OAAO,CAAC,SAAS,CAAC;IAoBxD;;;;OAIG;IACG,aAAa,CACf,eAAe,EAAC,cAAc,CAAC,UAAU,CAAC,GAC5C,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IAQrC;;;;;;;;;;OAUG;IACG,kBAAkB,CACpB,MAAM,EAAC,MAAM,EACb,MAAM,EAAC,MAAM,EACb,oBAAoB,EAAC,MAAM,GAC7B,OAAO,CAAC;QACN,MAAM,EAAC;YAAE,MAAM,EAAC,MAAM,CAAC;YAAC,MAAM,EAAC,MAAM,CAAA;SAAE,EAAE,CAAC;QAC1C,OAAO,EAAC,CAAC,OAAO,EAAC,cAAc,EAAE,KAAG,cAAc,CAAA;KACrD,CAAC;IAeI,WAAW,CAAE,IAAI,EAAC,UAAU,GAAE,OAAO,CAAC,UAAU,CAAC;IA2BjD,WAAW,CAAE,eAAe,EAAC,UAAU,GAAE,OAAO,CAAC,UAAU,CAAC;CAqBrE"}
@@ -1,6 +1,6 @@
1
1
  import { webcrypto } from '@substrate-system/one-webcrypto';
2
2
  import * as u from 'uint8arrays';
3
- import { decryptStream, decryptStreamRange, encryptStream, KEY_LENGTH, } from './ece.js';
3
+ import { decryptStream, decryptStreamRange, deriveContentSalt, encryptStream, header as eceHeader, encryptRecord as eceEncryptRecord, KEY_LENGTH, RECORD_SIZE, } from './ece.js';
4
4
  import { randomBuf, joinBufs, asBufferSource } from './util.js';
5
5
  export { encryptedSize, plaintextSize } from './ece.js';
6
6
  const IV_LENGTH = 12;
@@ -96,17 +96,102 @@ export class Keychain {
96
96
  setAuthToken(authToken) {
97
97
  this.authTokenPromise = Promise.resolve(decodeBits(authToken));
98
98
  }
99
+ /**
100
+ * SHA-256 digest of the plaintext, used as the input to content-bound
101
+ * salt derivation. Accepts a stream, a byte array, or a Blob;
102
+ * equivalent content yields the same digest.
103
+ *
104
+ * Pass the result to `encryptStream`/`header`/`encryptRecord` as
105
+ * `contentDigest`. The salt is derived from this digest internally,
106
+ * so the Keychain API never exposes a raw salt — a fixed salt can
107
+ * never pair with two different plaintexts.
108
+ *
109
+ * NOTE: WebCrypto has no incremental hash, so a stream/Blob is
110
+ * drained into memory before hashing.
111
+ *
112
+ * @param content Plaintext as a ReadableStream, Uint8Array, or Blob.
113
+ * @returns 32-byte SHA-256 digest.
114
+ */
115
+ async contentDigest(content) {
116
+ let bytes;
117
+ if (content instanceof Uint8Array) {
118
+ bytes = content;
119
+ }
120
+ else if (content instanceof ReadableStream) {
121
+ bytes = new Uint8Array(await new Response(content).arrayBuffer());
122
+ }
123
+ else if (typeof Blob !== 'undefined' && content instanceof Blob) {
124
+ bytes = new Uint8Array(await content.arrayBuffer());
125
+ }
126
+ else {
127
+ throw new TypeError('content must be a ReadableStream, Uint8Array, or Blob');
128
+ }
129
+ const digest = await webcrypto.subtle.digest('SHA-256', asBufferSource(bytes));
130
+ return new Uint8Array(digest);
131
+ }
99
132
  /**
100
133
  * Take a stream, return an encrypted stream.
101
- * @param stream Input stream
102
- * @returns {Promise<ReadableStream>}
134
+ *
135
+ * With `opts.contentDigest`, the ECE salt is derived from the digest
136
+ * internally (`deriveContentSalt`), so two calls over identical input
137
+ * produce byte-identical ciphertext (reproducible encryption). With no
138
+ * opts, a fresh random salt is used (today's behavior).
139
+ *
140
+ * The salt is never accepted directly: because it is bound to the
141
+ * content digest, a fixed salt can never encrypt two different
142
+ * plaintexts (AES-GCM nonce-reuse is structurally unreachable from
143
+ * this API).
144
+ *
145
+ * @param stream Input plaintext stream.
146
+ * @param opts Optional `{ contentDigest?, recordSize? }`.
147
+ * @returns Encrypted stream.
103
148
  */
104
- async encryptStream(stream) {
149
+ async encryptStream(stream, opts) {
105
150
  if (!(stream instanceof ReadableStream)) {
106
151
  throw new TypeError('This is not a readable stream');
107
152
  }
108
153
  const mainKey = await this.mainKeyPromise;
109
- return encryptStream(stream, mainKey);
154
+ const rs = opts?.recordSize ?? RECORD_SIZE;
155
+ if (opts?.contentDigest) {
156
+ const salt = await deriveContentSalt(mainKey, opts.contentDigest);
157
+ return encryptStream(stream, mainKey, rs, salt);
158
+ }
159
+ return encryptStream(stream, mainKey, rs);
160
+ }
161
+ /**
162
+ * Build the 21-byte ECE header for content identified by
163
+ * `contentDigest`. The salt is derived internally from the digest,
164
+ * so this never exposes a raw salt. The header is byte-identical to
165
+ * the header that `encryptStream({ contentDigest, recordSize })`
166
+ * emits for the same input.
167
+ *
168
+ * @param opts `{ contentDigest, recordSize? }`.
169
+ * @returns The 21-byte header.
170
+ */
171
+ async header(opts) {
172
+ const mainKey = await this.mainKeyPromise;
173
+ const salt = await deriveContentSalt(mainKey, opts.contentDigest);
174
+ return eceHeader(salt, opts.recordSize ?? RECORD_SIZE);
175
+ }
176
+ /**
177
+ * Encrypt a single ECE record by index, byte-identical to record
178
+ * `seq` of `encryptStream({ contentDigest, recordSize })`. The salt
179
+ * is derived from `contentDigest` internally; no raw salt is
180
+ * accepted.
181
+ *
182
+ * Non-final records must be exactly `recordPlaintextSize(recordSize)`
183
+ * bytes; the final record must be `<=` that. The low-level function
184
+ * throws otherwise.
185
+ *
186
+ * @param seq Zero-based record index.
187
+ * @param plaintext The record's plaintext slice.
188
+ * @param opts `{ isLast, contentDigest, recordSize? }`.
189
+ * @returns The encrypted record bytes.
190
+ */
191
+ async encryptRecord(seq, plaintext, opts) {
192
+ const mainKey = await this.mainKeyPromise;
193
+ const salt = await deriveContentSalt(mainKey, opts.contentDigest);
194
+ return eceEncryptRecord(mainKey, seq, plaintext, opts.isLast, salt, opts.recordSize ?? RECORD_SIZE);
110
195
  }
111
196
  /**
112
197
  * Encrypt and return some data; don't stream.
@@ -1 +1 @@
1
- {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/keychain.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"keychain.js","sourceRoot":"","sources":["../../src/keychain.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@substrate-system/crypto-stream",
3
3
  "description": "Streaming encryption for the browser",
4
4
  "type": "module",
5
- "version": "0.0.35",
5
+ "version": "0.1.0",
6
6
  "main": "dist/index.js",
7
7
  "files": [
8
8
  "./dist/*"