@macula-io/ts 0.19.0 → 0.20.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
@@ -20,7 +20,8 @@
20
20
  ---
21
21
 
22
22
  > **Status, 2026-09-26:** on the **macula 12** wire (post-quantum: ML-DSA-87
23
- > identities, ML-KEM hybrid key exchange, signed requests), over macula-go's
23
+ > identities, as the ML-DSA-87 + RSA-PSS-4096 composite in `pq_hybrid`, the
24
+ > fleet's profile; ML-KEM hybrid key exchange; signed requests), over macula-go's
24
25
  > pool. Calls and streams by direct dial, serving (under an org or in a node's
25
26
  > own namespace), publish/subscribe, the DHT and node-served content are
26
27
  > tested against in-process macula 12 stations on every `npm test`.
@@ -60,7 +61,7 @@ that's actually usable for this today:
60
61
 
61
62
  macula-go, macula-rust, macula-dotnet, and macula-php have all already
62
63
  proven this protocol works and are actively maintained. Rather than
63
- reimplement QUIC, post-quantum TLS, deterministic CBOR and signed frames a fifth time in a
64
+ reimplement QUIC, TLS 1.3 with a hybrid post-quantum key exchange, deterministic CBOR and signed frames a fifth time in a
64
65
  language with no mature QUIC story of its own, macula-ts reuses macula-go's
65
66
  already-proven implementation through FFI — the same tradeoff
66
67
  [macula-php](https://github.com/macula-io/macula-php) already made
@@ -154,7 +155,7 @@ a Promise; events, served calls and served streams reach JavaScript through a
154
155
 
155
156
  | Primitive | Caller | Provider | Notes |
156
157
  |---|---|---|---|
157
- | Node keys (`NodeKey`) | ✅ | ✅ | `pq_hybrid` (the fleet's) or `pq_pure`; key files readable by the owner only |
158
+ | Node keys (`NodeKey`) | ✅ | ✅ | `pq_hybrid` (the fleet's) or `pq_pure`; key files readable by the owner only; `sign` and `NodeKey.verify`, pq_hybrid checked against the LAMPS draft's own vector and cross-verified with macula 12.7.0 |
158
159
  | Pool of station links (`Pool.connect`) | ✅ | ✅ | Seeds pinned by node_id; realm keys pinned; links redialed with subscriptions and served procedures replayed |
159
160
  | Calls by direct dial (`call`, `providers`) | ✅ | ✅ | `serve`: a thrown error goes back as `handler_error`; errors arrive as `ProviderError` / `RelayError` |
160
161
  | A node's own namespace (`ownProcedure`) | ✅ | ✅ | `~<node_id>/<name>`: served and called with no org and no realm key; the node's signature authorizes it |
@@ -183,6 +184,13 @@ keys, calls by direct dial and their errors, providers, server and client
183
184
  streams (and that no stream is left unreleased), pubsub and the DHT, through
184
185
  the real addon. No network is needed.
185
186
 
187
+ `src/lamps.test.ts` holds pq_hybrid, the LAMPS composite
188
+ id-MLDSA87-RSA4096-PSS-SHA512, to `draft-ietf-lamps-pq-composite-sigs`' own
189
+ vector (the one macula and macula-go check), and to composites that crossed
190
+ both ways with macula 12.x. `scripts/cross-verify-macula.sh` renews those: this
191
+ SDK signs, macula (from hex, in the image macula's own CI runs in) verifies
192
+ and signs its own, and this SDK verifies it.
193
+
186
194
  `src/fleet.live.test.ts` runs against one real station and is not part of
187
195
  `npm test`. It needs `MACULA_TS_LIVE_SEED` (host:port), `MACULA_TS_LIVE_STATION_ID`
188
196
  (the station's node_id), `MACULA_TS_LIVE_REALM` and `MACULA_TS_LIVE_REALM_KEY`;
package/dist/binding.d.ts CHANGED
@@ -18,6 +18,7 @@ export declare const native: {
18
18
  keyProfile(key: Handle): string;
19
19
  keySign(key: Handle, data: Uint8Array): Promise<Uint8Array>;
20
20
  keyFree(key: Handle): void;
21
+ verify(data: Uint8Array, signature: Uint8Array, publicKey: Uint8Array, profile: string): boolean;
21
22
  poolConnect(key: Handle, seedsJson: string, optionsJson: string): Promise<Handle>;
22
23
  poolClose(pool: Handle): Promise<void>;
23
24
  poolNodeId(pool: Handle): Uint8Array;
@@ -1 +1 @@
1
- {"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,oEAAoE;AACpE,4EAA4E;AAC5E,2EAA2E;AAC3E,0EAA0E;AAC1E,yBAAyB;AACzB,EAAE;AACF,4EAA4E;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAgBrE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CA+CvD,CAAC"}
1
+ {"version":3,"file":"binding.js","sourceRoot":"","sources":["../src/binding.ts"],"names":[],"mappings":"AAAA,6EAA6E;AAC7E,oEAAoE;AACpE,4EAA4E;AAC5E,2EAA2E;AAC3E,0EAA0E;AAC1E,yBAAyB;AACzB,EAAE;AACF,4EAA4E;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE1C,MAAM,OAAO,GAAG,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAgBrE,8DAA8D;AAC9D,MAAM,CAAC,MAAM,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,CAgDvD,CAAC"}
package/dist/key.d.ts CHANGED
@@ -24,6 +24,11 @@ export declare class NodeKey {
24
24
  profile(): Profile;
25
25
  /** Signs data as given. */
26
26
  sign(data: Uint8Array): Promise<Uint8Array>;
27
+ /** Whether signature is valid over data for a public key as carried on the
28
+ * wire (publicKey()), under profile: ML-DSA-87 in pq_pure, and in pq_hybrid
29
+ * the LAMPS composite id-MLDSA87-RSA4096-PSS-SHA512 with the empty context,
30
+ * both halves verified. Anything malformed is false. */
31
+ static verify(data: Uint8Array, signature: Uint8Array, publicKey: Uint8Array, profile?: Profile): boolean;
27
32
  /** Frees the native key. The NodeKey is unusable after. */
28
33
  free(): void;
29
34
  /** @internal */
package/dist/key.js CHANGED
@@ -56,6 +56,13 @@ export class NodeKey {
56
56
  async sign(data) {
57
57
  return native.keySign(this.live(), data);
58
58
  }
59
+ /** Whether signature is valid over data for a public key as carried on the
60
+ * wire (publicKey()), under profile: ML-DSA-87 in pq_pure, and in pq_hybrid
61
+ * the LAMPS composite id-MLDSA87-RSA4096-PSS-SHA512 with the empty context,
62
+ * both halves verified. Anything malformed is false. */
63
+ static verify(data, signature, publicKey, profile = "pq_hybrid") {
64
+ return native.verify(data, signature, publicKey, profile);
65
+ }
59
66
  /** Frees the native key. The NodeKey is unusable after. */
60
67
  free() {
61
68
  if (this.handle !== null)
package/dist/key.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"key.js","sourceRoot":"","sources":["../src/key.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,cAAc;AACd,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAe,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAKhC,MAAM,OAAO,OAAO;IACU,MAAM;IAAlC,YAA4B,MAAqB;sBAArB,MAAM;IAAkB,CAAC;IAErD;iCAC6B;IAC7B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAY,WAAW;QAClD,OAAO,IAAI,OAAO,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;0DACsD;IACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAO,GAAY,WAAW;QAC5D,OAAO,IAAI,OAAO,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,8EAA8E;IAC9E,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,OAAO,GAAY,WAAW;QACpE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,iCAAiC;IACjC,MAAM;QACJ,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,oCAAoC;IACpC,SAAS;QACP,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,yBAAyB;IACzB,OAAO;QACL,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAY,CAAC;IACnD,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,IAAI,CAAC,IAAgB;QACzB,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED,2DAA2D;IAC3D,IAAI;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;YAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,gBAAgB;IAChB,IAAI;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
1
+ {"version":3,"file":"key.js","sourceRoot":"","sources":["../src/key.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,6EAA6E;AAC7E,4EAA4E;AAC5E,cAAc;AACd,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAe,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AAKhC,MAAM,OAAO,OAAO;IACU,MAAM;IAAlC,YAA4B,MAAqB;sBAArB,MAAM;IAAkB,CAAC;IAErD;iCAC6B;IAC7B,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAY,WAAW;QAClD,OAAO,IAAI,OAAO,CAAC,MAAM,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,CAAC;IAED;0DACsD;IACtD,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAO,GAAY,WAAW;QAC5D,OAAO,IAAI,OAAO,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC1D,CAAC;IAED,8EAA8E;IAC9E,MAAM,CAAC,KAAK,CAAC,YAAY,CAAC,IAAY,EAAE,OAAO,GAAY,WAAW;QACpE,IAAI,CAAC;YACH,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QACrB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;YAC5C,MAAM,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACrC,CAAC;IAED,0DAA0D;IAC1D,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,iCAAiC;IACjC,MAAM;QACJ,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IACvC,CAAC;IAED,oCAAoC;IACpC,SAAS;QACP,OAAO,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IAC5B,CAAC;IAED,6CAA6C;IAC7C,SAAS;QACP,OAAO,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,yBAAyB;IACzB,OAAO;QACL,OAAO,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAY,CAAC;IACnD,CAAC;IAED,2BAA2B;IAC3B,KAAK,CAAC,IAAI,CAAC,IAAgB;QACzB,OAAO,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,IAAI,CAAC,CAAC;IAC3C,CAAC;IAED;;;4DAGwD;IACxD,MAAM,CAAC,MAAM,CAAC,IAAgB,EAAE,SAAqB,EAAE,SAAqB,EAAE,OAAO,GAAY,WAAW;QAC1G,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC;IAED,2DAA2D;IAC3D,IAAI;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;YAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACtD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,gBAAgB;IAChB,IAAI;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QAC/E,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@macula-io/ts",
3
- "version": "0.19.0",
3
+ "version": "0.20.0",
4
4
  "description": "TypeScript SDK for the Macula mesh (FFI over macula-go)",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [