dstu-core 0.1.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/js/secretstream.js +17 -7
  2. package/package.json +6 -6
@@ -9,9 +9,11 @@
9
9
  * standing pitfalls this port re-checks below).
10
10
  *
11
11
  * Wire format matches `uacrypt encrypt`/`decrypt` exactly (crates/uacrypt/src/lib.rs's
12
- * run_secretstream_encrypt/run_secretstream_decrypt, D-68): `header (32 bytes)` followed by one
13
- * record per chunk, `tagByte (1) || chunkLenU32LE (4) || ciphertext (chunkLen) || authTag (16)`,
14
- * chunks capped at 8 KiB (matching SECRETSTREAM_CHUNK_BYTES, not an independent choice).
12
+ * run_secretstream_encrypt/run_secretstream_decrypt, D-68): `version (1) || header (32 bytes)`
13
+ * followed by one record per chunk, `tagByte (1) || chunkLenU32LE (4) || ciphertext (chunkLen) ||
14
+ * authTag (16)`. Every record but the Final one is exactly 8 KiB (SECRETSTREAM_CHUNK_BYTES, part of
15
+ * the format since D-208, not an independent choice). The shared vectors in
16
+ * crates/dstu-core/tests/vectors/secretstream-file/ pin this.
15
17
  */
16
18
 
17
19
  const { Transform } = require('node:stream');
@@ -21,6 +23,8 @@ const native = require('../native/index.js');
21
23
  // interop with `uacrypt encrypt`/`decrypt`, not an independent choice.
22
24
  const CHUNK_BYTES = 8 * 1024;
23
25
  const AUTH_TAG_BYTES = 16;
26
+ // Matches dstu-core's crypto_secretstream::FORMAT_VERSION (D-208); the shared vectors pin it.
27
+ const FORMAT_VERSION = 2;
24
28
 
25
29
  /**
26
30
  * Write-only Transform: buffers input and pushes each full 8 KiB chunk downstream as it fills,
@@ -42,7 +46,7 @@ class SecretStreamEncryptor extends Transform {
42
46
  super(options);
43
47
  this._pushState = new native.SecretStreamPushState(key);
44
48
  this._buf = Buffer.alloc(0);
45
- this.push(this._pushState.header);
49
+ this.push(Buffer.concat([Buffer.from([FORMAT_VERSION]), this._pushState.header]));
46
50
  }
47
51
 
48
52
  _pushChunk(tag, data) {
@@ -122,9 +126,12 @@ class SecretStreamDecryptor extends Transform {
122
126
 
123
127
  _drain() {
124
128
  if (!this._pullState) {
125
- if (this._buf.length < 32) return;
126
- const header = this._buf.subarray(0, 32);
127
- this._buf = this._buf.subarray(32);
129
+ if (this._buf.length >= 1 && this._buf[0] !== FORMAT_VERSION) {
130
+ throw new Error(`unsupported stream format version ${this._buf[0]} (this build reads ${FORMAT_VERSION})`);
131
+ }
132
+ if (this._buf.length < 33) return;
133
+ const header = this._buf.subarray(1, 33);
134
+ this._buf = this._buf.subarray(33);
128
135
  this._pullState = new native.SecretStreamPullState(this._key, header);
129
136
  }
130
137
  for (;;) {
@@ -140,6 +147,9 @@ class SecretStreamDecryptor extends Transform {
140
147
  if (chunkLen > CHUNK_BYTES) {
141
148
  throw new Error(`secretstream chunk too large: declared ${chunkLen} bytes, max ${CHUNK_BYTES}`);
142
149
  }
150
+ if (tagByte !== native.SECRETSTREAM_TAG_FINAL && chunkLen !== CHUNK_BYTES) {
151
+ throw new Error(`non-final chunk of ${chunkLen} bytes, must be exactly ${CHUNK_BYTES} (D-208)`);
152
+ }
143
153
  const recordLen = 5 + chunkLen + AUTH_TAG_BYTES;
144
154
  if (this._buf.length < recordLen) return;
145
155
  const ciphertext = this._buf.subarray(5, 5 + chunkLen);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dstu-core",
3
- "version": "0.1.1",
3
+ "version": "0.3.0",
4
4
  "private": false,
5
5
  "description": "Node.js bindings for dstu-core (Ukrainian DSTU cryptographic standards)",
6
6
  "main": "js/index.js",
@@ -42,14 +42,14 @@
42
42
  "scripts": {
43
43
  "build": "napi build native --platform --release",
44
44
  "build:debug": "napi build native --platform",
45
- "test": "node --test",
45
+ "test": "node --expose-gc --test",
46
46
  "lint": "eslint .",
47
47
  "prepublishOnly": "napi prepublish -t npm --skip-gh-release"
48
48
  },
49
49
  "optionalDependencies": {
50
- "dstu-core-linux-x64-gnu": "0.1.1",
51
- "dstu-core-darwin-arm64": "0.1.1",
52
- "dstu-core-win32-x64-msvc": "0.1.1",
53
- "dstu-core-linux-arm64-gnu": "0.1.1"
50
+ "dstu-core-linux-x64-gnu": "0.3.0",
51
+ "dstu-core-darwin-arm64": "0.3.0",
52
+ "dstu-core-win32-x64-msvc": "0.3.0",
53
+ "dstu-core-linux-arm64-gnu": "0.3.0"
54
54
  }
55
55
  }