space-data-module-sdk 0.8.4 → 0.8.6

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 (354) hide show
  1. package/README.md +117 -20
  2. package/bin/space-data-module.js +263 -0
  3. package/docs/.nojekyll +1 -0
  4. package/docs/AGENTS.md +34 -0
  5. package/docs/architecture.svg +141 -0
  6. package/docs/browser-wasmedge-isomorphic.md +179 -0
  7. package/docs/flatsql-streaming-standard.md +341 -0
  8. package/docs/gpu-module-abi.md +193 -0
  9. package/docs/index.html +125 -0
  10. package/docs/isomorphic-pthreads.md +188 -0
  11. package/docs/isomorphic-sdn-runtime-plan.md +167 -0
  12. package/docs/language-runtime-matrix.md +82 -0
  13. package/docs/manifest-structure.svg +114 -0
  14. package/docs/module-bundle-runtime-plan.md +19 -0
  15. package/docs/module-lifecycle.svg +70 -0
  16. package/docs/module-publication-standard.md +540 -0
  17. package/docs/node-red-default-node-parity.md +88 -0
  18. package/docs/protocol-installation.md +196 -0
  19. package/docs/secrets-capability.md +152 -0
  20. package/docs/styles.css +288 -0
  21. package/docs/testing-harness.md +408 -0
  22. package/docs/tri-runtime-parity.md +132 -0
  23. package/docs/wallet-callback.html +2 -0
  24. package/package.json +25 -6
  25. package/schemas/HttpRequestAbi.fbs +41 -0
  26. package/schemas/HttpResponseAbi.fbs +36 -0
  27. package/schemas/PluginManifest.fbs +2 -1
  28. package/src/AGENTS.md +1 -1
  29. package/src/app/codec.js +548 -0
  30. package/src/app/index.js +6 -0
  31. package/src/browser.js +5 -0
  32. package/src/bundle/constants.js +1 -0
  33. package/src/bundle/index.js +15 -0
  34. package/src/bundle/sigdomain.js +179 -0
  35. package/src/bundle/signing.js +767 -0
  36. package/src/bundle/wasm.js +3 -2
  37. package/src/capabilities.js +3 -0
  38. package/src/compat/index.js +7 -0
  39. package/src/compat/sdnLegacy.js +449 -0
  40. package/src/compiler/compileModule.js +556 -55
  41. package/src/compiler/flatcSupport.js +41 -27
  42. package/src/compiler/index.d.ts +2 -0
  43. package/src/compiler/index.js +18 -0
  44. package/src/compiler/invokeGlue.js +1212 -183
  45. package/src/compiler/pthreadArtifactGuard.js +910 -0
  46. package/src/compiler/sdnShimGenerator.js +323 -0
  47. package/src/compiler/wasiThreadsToolchain.js +150 -0
  48. package/src/compliance/index.js +11 -1
  49. package/src/compliance/legacyWildcardPorts.js +228 -0
  50. package/src/compliance/pluginCompliance.js +1000 -96
  51. package/src/field-stream/index.d.ts +31 -0
  52. package/src/field-stream/index.js +119 -0
  53. package/src/flow/dependencyStreamBridge.js +234 -0
  54. package/src/flow/flatsqlLinkShim.js +304 -0
  55. package/src/flow/flowCodec.js +107 -0
  56. package/src/flow/flowCompiler.js +2900 -0
  57. package/src/flow/flowRuntimeHost.js +877 -0
  58. package/src/flow/index.d.ts +117 -0
  59. package/src/flow/index.js +31 -0
  60. package/src/flow/isomorphicFlowHost.js +384 -0
  61. package/src/flow/jsFlowRuntime.js +275 -0
  62. package/src/flow/normalize.js +294 -0
  63. package/src/flow/runtime-src/flow_runtime.cpp +1699 -0
  64. package/src/flow/vendor/sdn-flow/MethodRegistry.js +400 -0
  65. package/src/flow/vendor/sdn-flow/constants.js +39 -0
  66. package/src/flow/vendor/sdn-flow/index.js +29 -0
  67. package/src/flow/vendor/sdn-flow/normalize.js +506 -0
  68. package/src/flow/vendor/sdn-flow/wasmCompatibility.js +189 -0
  69. package/src/generated/http/cpp/HttpRequestAbi_generated.h +285 -0
  70. package/src/generated/http/cpp/HttpResponseAbi_generated.h +192 -0
  71. package/src/generated/http/sdn/http/http-header.js +53 -0
  72. package/src/generated/http/sdn/http/http-header.ts +67 -0
  73. package/src/generated/http/sdn/http/http-request.js +132 -0
  74. package/src/generated/http/sdn/http/http-request.ts +179 -0
  75. package/src/generated/http/sdn/http/http-response.js +144 -0
  76. package/src/generated/http/sdn/http/http-response.ts +168 -0
  77. package/src/generated/http/sdn/http.js +11 -0
  78. package/src/generated/http/sdn/http.ts +4 -0
  79. package/src/generated/orbpro/flow/backpressure-policy.d.ts +12 -0
  80. package/src/generated/orbpro/flow/backpressure-policy.d.ts.map +1 -0
  81. package/src/generated/orbpro/flow/backpressure-policy.js +17 -0
  82. package/src/generated/orbpro/flow/backpressure-policy.js.map +1 -0
  83. package/src/generated/orbpro/flow/backpressure-policy.ts +15 -0
  84. package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts +142 -0
  85. package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts.map +1 -0
  86. package/src/generated/orbpro/flow/flow-bundle-manifest.js +304 -0
  87. package/src/generated/orbpro/flow/flow-bundle-manifest.js.map +1 -0
  88. package/src/generated/orbpro/flow/flow-bundle-manifest.ts +399 -0
  89. package/src/generated/orbpro/flow/flow-edge.d.ts +113 -0
  90. package/src/generated/orbpro/flow/flow-edge.d.ts.map +1 -0
  91. package/src/generated/orbpro/flow/flow-edge.js +221 -0
  92. package/src/generated/orbpro/flow/flow-edge.js.map +1 -0
  93. package/src/generated/orbpro/flow/flow-edge.ts +292 -0
  94. package/src/generated/orbpro/flow/flow-node.d.ts +80 -0
  95. package/src/generated/orbpro/flow/flow-node.d.ts.map +1 -0
  96. package/src/generated/orbpro/flow/flow-node.js +158 -0
  97. package/src/generated/orbpro/flow/flow-node.js.map +1 -0
  98. package/src/generated/orbpro/flow/flow-node.ts +202 -0
  99. package/src/generated/orbpro/flow/flow-program.d.ts +164 -0
  100. package/src/generated/orbpro/flow/flow-program.d.ts.map +1 -0
  101. package/src/generated/orbpro/flow/flow-program.js +350 -0
  102. package/src/generated/orbpro/flow/flow-program.js.map +1 -0
  103. package/src/generated/orbpro/flow/flow-program.ts +477 -0
  104. package/src/generated/orbpro/flow/flow-trigger.d.ts +108 -0
  105. package/src/generated/orbpro/flow/flow-trigger.d.ts.map +1 -0
  106. package/src/generated/orbpro/flow/flow-trigger.js +207 -0
  107. package/src/generated/orbpro/flow/flow-trigger.js.map +1 -0
  108. package/src/generated/orbpro/flow/flow-trigger.ts +276 -0
  109. package/src/generated/orbpro/flow/node-kind.d.ts +13 -0
  110. package/src/generated/orbpro/flow/node-kind.d.ts.map +1 -0
  111. package/src/generated/orbpro/flow/node-kind.js +16 -0
  112. package/src/generated/orbpro/flow/node-kind.js.map +1 -0
  113. package/src/generated/orbpro/{invoke.ts → flow/node-kind.ts} +12 -2
  114. package/src/generated/orbpro/flow/plugin-version-binding.d.ts +52 -0
  115. package/src/generated/orbpro/flow/plugin-version-binding.d.ts.map +1 -0
  116. package/src/generated/orbpro/flow/plugin-version-binding.js +85 -0
  117. package/src/generated/orbpro/flow/plugin-version-binding.js.map +1 -0
  118. package/src/generated/orbpro/flow/plugin-version-binding.ts +121 -0
  119. package/src/generated/orbpro/flow/schema-hash-binding.d.ts +70 -0
  120. package/src/generated/orbpro/flow/schema-hash-binding.d.ts.map +1 -0
  121. package/src/generated/orbpro/flow/schema-hash-binding.js +143 -0
  122. package/src/generated/orbpro/flow/schema-hash-binding.js.map +1 -0
  123. package/src/generated/orbpro/flow/schema-hash-binding.ts +189 -0
  124. package/src/generated/orbpro/flow/trigger-binding.d.ts +71 -0
  125. package/src/generated/orbpro/flow/trigger-binding.d.ts.map +1 -0
  126. package/src/generated/orbpro/flow/trigger-binding.js +142 -0
  127. package/src/generated/orbpro/flow/trigger-binding.js.map +1 -0
  128. package/src/generated/orbpro/flow/trigger-binding.ts +181 -0
  129. package/src/generated/orbpro/flow/trigger-kind.d.ts +14 -0
  130. package/src/generated/orbpro/flow/trigger-kind.d.ts.map +1 -0
  131. package/src/generated/orbpro/flow/trigger-kind.js +17 -0
  132. package/src/generated/orbpro/flow/trigger-kind.js.map +1 -0
  133. package/src/generated/orbpro/flow/trigger-kind.ts +17 -0
  134. package/src/generated/orbpro/flow.d.ts +21 -0
  135. package/src/generated/orbpro/flow.d.ts.map +1 -0
  136. package/src/generated/orbpro/flow.js +23 -0
  137. package/src/generated/orbpro/flow.js.map +1 -0
  138. package/src/generated/orbpro/flow.ts +24 -0
  139. package/src/generated/orbpro/manifest/capability-kind.d.ts +2 -1
  140. package/src/generated/orbpro/manifest/capability-kind.js +1 -0
  141. package/src/generated/orbpro/manifest/capability-kind.ts +1 -0
  142. package/src/generated/orbpro/plugin/stream-invoke-request.d.ts +93 -0
  143. package/src/generated/orbpro/plugin/stream-invoke-request.js +160 -0
  144. package/src/generated/orbpro/plugin/stream-invoke-request.ts +211 -0
  145. package/src/generated/orbpro/plugin/stream-invoke-response.d.ts +99 -0
  146. package/src/generated/orbpro/plugin/stream-invoke-response.js +175 -0
  147. package/src/generated/orbpro/plugin/stream-invoke-response.ts +226 -0
  148. package/src/generated/orbpro/plugin.js +8 -0
  149. package/src/generated/orbpro/stream.d.ts +12 -0
  150. package/src/generated/orbpro/stream.js +14 -0
  151. package/src/generated/orbpro/stream.ts +15 -0
  152. package/src/generated/spacedatastandards/plg/EntryFunction.d.ts +52 -0
  153. package/src/generated/spacedatastandards/plg/EntryFunction.d.ts.map +1 -0
  154. package/src/generated/spacedatastandards/plg/EntryFunction.js +106 -0
  155. package/src/generated/spacedatastandards/plg/EntryFunction.ts +162 -0
  156. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts +90 -0
  157. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts.map +1 -0
  158. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.js +189 -0
  159. package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.ts +270 -0
  160. package/src/generated/spacedatastandards/plg/PLG.d.ts +492 -0
  161. package/src/generated/spacedatastandards/plg/PLG.d.ts.map +1 -0
  162. package/src/generated/spacedatastandards/plg/PLG.js +1139 -0
  163. package/src/generated/spacedatastandards/plg/PLG.ts +1600 -0
  164. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts +63 -0
  165. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts.map +1 -0
  166. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.js +138 -0
  167. package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.ts +189 -0
  168. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts +41 -0
  169. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts.map +1 -0
  170. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.js +104 -0
  171. package/src/generated/spacedatastandards/plg/PLGBuildArtifact.ts +151 -0
  172. package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts +68 -0
  173. package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts.map +1 -0
  174. package/src/generated/spacedatastandards/plg/PLGFlowEdge.js +124 -0
  175. package/src/generated/spacedatastandards/plg/PLGFlowEdge.ts +184 -0
  176. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts +58 -0
  177. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts.map +1 -0
  178. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.js +126 -0
  179. package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.ts +161 -0
  180. package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts +82 -0
  181. package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts.map +1 -0
  182. package/src/generated/spacedatastandards/plg/PLGFlowNode.js +164 -0
  183. package/src/generated/spacedatastandards/plg/PLGFlowNode.ts +244 -0
  184. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts +55 -0
  185. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts.map +1 -0
  186. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.js +105 -0
  187. package/src/generated/spacedatastandards/plg/PLGFlowTrigger.ts +162 -0
  188. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts +42 -0
  189. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts.map +1 -0
  190. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.js +83 -0
  191. package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.ts +127 -0
  192. package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts +36 -0
  193. package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts.map +1 -0
  194. package/src/generated/spacedatastandards/plg/PLGHostCapability.js +90 -0
  195. package/src/generated/spacedatastandards/plg/PLGHostCapability.ts +127 -0
  196. package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts +53 -0
  197. package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts.map +1 -0
  198. package/src/generated/spacedatastandards/plg/PLGMethodManifest.js +153 -0
  199. package/src/generated/spacedatastandards/plg/PLGMethodManifest.ts +210 -0
  200. package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts +70 -0
  201. package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts.map +1 -0
  202. package/src/generated/spacedatastandards/plg/PLGPortManifest.js +149 -0
  203. package/src/generated/spacedatastandards/plg/PLGPortManifest.ts +212 -0
  204. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts +73 -0
  205. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts.map +1 -0
  206. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.js +199 -0
  207. package/src/generated/spacedatastandards/plg/PLGProtocolSpec.ts +292 -0
  208. package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts +40 -0
  209. package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts.map +1 -0
  210. package/src/generated/spacedatastandards/plg/PLGTimerSpec.js +103 -0
  211. package/src/generated/spacedatastandards/plg/PLGTimerSpec.ts +148 -0
  212. package/src/generated/spacedatastandards/plg/PluginCapability.d.ts +41 -0
  213. package/src/generated/spacedatastandards/plg/PluginCapability.d.ts.map +1 -0
  214. package/src/generated/spacedatastandards/plg/PluginCapability.js +82 -0
  215. package/src/generated/spacedatastandards/plg/{plugin-capability.ts → PluginCapability.ts} +55 -18
  216. package/src/generated/spacedatastandards/plg/PluginDependency.d.ts +42 -0
  217. package/src/generated/spacedatastandards/plg/PluginDependency.d.ts.map +1 -0
  218. package/src/generated/spacedatastandards/plg/PluginDependency.js +80 -0
  219. package/src/generated/spacedatastandards/plg/PluginDependency.ts +124 -0
  220. package/src/generated/spacedatastandards/plg/TAB.d.ts +85 -0
  221. package/src/generated/spacedatastandards/plg/TAB.d.ts.map +1 -0
  222. package/src/generated/spacedatastandards/plg/TAB.js +173 -0
  223. package/src/generated/spacedatastandards/plg/TAB.ts +228 -0
  224. package/src/generated/spacedatastandards/plg/bufferMutability.d.ts +18 -0
  225. package/src/generated/spacedatastandards/plg/bufferMutability.d.ts.map +1 -0
  226. package/src/generated/spacedatastandards/plg/bufferMutability.js +20 -0
  227. package/src/generated/spacedatastandards/plg/bufferMutability.ts +23 -0
  228. package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts +18 -0
  229. package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts.map +1 -0
  230. package/src/generated/spacedatastandards/plg/bufferOwnership.js +20 -0
  231. package/src/generated/spacedatastandards/plg/bufferOwnership.ts +23 -0
  232. package/src/generated/spacedatastandards/plg/drainBehavior.d.ts +20 -0
  233. package/src/generated/spacedatastandards/plg/drainBehavior.d.ts.map +1 -0
  234. package/src/generated/spacedatastandards/plg/drainBehavior.js +22 -0
  235. package/src/generated/spacedatastandards/plg/drainBehavior.ts +25 -0
  236. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts +10 -0
  237. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts.map +1 -0
  238. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.js +12 -0
  239. package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.ts +13 -0
  240. package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts +51 -0
  241. package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts.map +1 -0
  242. package/src/generated/spacedatastandards/plg/hostCapabilityKind.js +53 -0
  243. package/src/generated/spacedatastandards/plg/hostCapabilityKind.ts +55 -0
  244. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts +15 -0
  245. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts.map +1 -0
  246. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.js +17 -0
  247. package/src/generated/spacedatastandards/plg/invokeSurfaceKind.ts +19 -0
  248. package/src/generated/spacedatastandards/plg/main.d.ts +29 -0
  249. package/src/generated/spacedatastandards/plg/main.d.ts.map +1 -0
  250. package/src/generated/spacedatastandards/plg/main.js +30 -0
  251. package/src/generated/spacedatastandards/plg/main.ts +32 -0
  252. package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts +17 -0
  253. package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts.map +1 -0
  254. package/src/generated/spacedatastandards/plg/payloadWireFormat.js +19 -0
  255. package/src/generated/spacedatastandards/plg/payloadWireFormat.ts +21 -0
  256. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts +82 -0
  257. package/src/generated/spacedatastandards/plg/pluginCategory.d.ts.map +1 -0
  258. package/src/generated/spacedatastandards/plg/pluginCategory.js +84 -0
  259. package/src/generated/spacedatastandards/plg/pluginCategory.ts +103 -0
  260. package/src/generated/spacedatastandards/plg/publicationState.d.ts +18 -0
  261. package/src/generated/spacedatastandards/plg/publicationState.d.ts.map +1 -0
  262. package/src/generated/spacedatastandards/plg/publicationState.js +20 -0
  263. package/src/generated/spacedatastandards/plg/purchaseTier.d.ts +18 -0
  264. package/src/generated/spacedatastandards/plg/purchaseTier.d.ts.map +1 -0
  265. package/src/generated/spacedatastandards/plg/purchaseTier.js +20 -0
  266. package/src/host/AGENTS.md +2 -2
  267. package/src/host/abi.js +53 -66
  268. package/src/host/browserHost.js +355 -8
  269. package/src/host/cpp/keyslotClient.hpp +231 -0
  270. package/src/host/cpp/secretsClient.hpp +583 -0
  271. package/src/host/hostcallWire.js +183 -0
  272. package/src/host/index.js +2 -0
  273. package/src/host/isomorphicLoader.js +44 -7
  274. package/src/host/nodeHost.js +227 -8
  275. package/src/host/sabHostcallChannel.js +206 -0
  276. package/src/host/timerDriver.js +203 -0
  277. package/src/host/wasiShim.js +41 -1
  278. package/src/host/wasiThreadBrowserWorker.mjs +48 -0
  279. package/src/host/wasiThreadHost.js +393 -0
  280. package/src/host/wasiThreadWorker.mjs +32 -0
  281. package/src/host/wasiThreadWorkerRuntime.js +93 -0
  282. package/src/http/index.js +339 -0
  283. package/src/index.d.ts +725 -11
  284. package/src/index.js +4 -0
  285. package/src/invoke/codec.js +1202 -128
  286. package/src/invoke/index.js +5 -1
  287. package/src/licensing/index.d.ts +2 -0
  288. package/src/licensing/index.js +2 -0
  289. package/src/licensing/records.js +287 -8
  290. package/src/manifest/codec.js +62 -14
  291. package/src/manifest/index.js +2 -0
  292. package/src/manifest/legacyToPlg.js +164 -25
  293. package/src/manifest/normalize.js +1 -0
  294. package/src/manifest/plgCodec.js +1303 -62
  295. package/src/manifest/typeRefs.js +162 -24
  296. package/src/runtime/compiledRuntimeAbi.js +47 -0
  297. package/src/runtime/compiledRuntimeAbi.json +33 -0
  298. package/src/runtime/index.d.ts +32 -0
  299. package/src/runtime/index.js +1 -0
  300. package/src/runtime-host/index.js +3 -0
  301. package/src/runtime-host/methodRegistry.js +55 -0
  302. package/src/standards/index.js +200 -56
  303. package/src/standards/sharedCatalog.js +16 -0
  304. package/src/testing/browserModuleHarness.js +604 -31
  305. package/src/testing/docker/wasmedge-parity.Dockerfile +39 -0
  306. package/src/testing/index.d.ts +151 -0
  307. package/src/testing/index.js +21 -0
  308. package/src/testing/native/wasmedge_emscripten_pthread_runner.c +25 -1
  309. package/src/testing/parityBrowserRunner.js +138 -0
  310. package/src/testing/parityHarness.js +616 -0
  311. package/src/testing/parityLanes.js +537 -0
  312. package/src/testing/processInvoke.js +29 -21
  313. package/src/testing/streamInvokeCodec.js +10 -175
  314. package/src/testing/wasmedgePin.json +6 -0
  315. package/src/testing/workerModuleHarness.js +242 -0
  316. package/src/testing/workerModuleHarnessWorker.js +176 -0
  317. package/src/transport/index.js +3 -0
  318. package/src/transport/pki.js +352 -14
  319. package/src/transport/records.js +16 -7
  320. package/src/utils/ecdsaDer.js +106 -0
  321. package/src/utils/wasmCrypto.js +0 -43
  322. package/templates/gpu-module/README.md +48 -0
  323. package/templates/gpu-module/include/space_data_gpu_abi.h +122 -0
  324. package/templates/gpu-module/manifest.json +84 -0
  325. package/schemas/PluginInvokeRequest.fbs +0 -18
  326. package/schemas/PluginInvokeResponse.fbs +0 -30
  327. package/schemas/spacedatastandards/PLG.fbs +0 -191
  328. package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts +0 -51
  329. package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts.map +0 -1
  330. package/src/generated/orbpro/invoke/plugin-invoke-request.js +0 -131
  331. package/src/generated/orbpro/invoke/plugin-invoke-request.js.map +0 -1
  332. package/src/generated/orbpro/invoke/plugin-invoke-request.ts +0 -173
  333. package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts +0 -76
  334. package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts.map +0 -1
  335. package/src/generated/orbpro/invoke/plugin-invoke-response.js +0 -184
  336. package/src/generated/orbpro/invoke/plugin-invoke-response.js.map +0 -1
  337. package/src/generated/orbpro/invoke/plugin-invoke-response.ts +0 -243
  338. package/src/generated/orbpro/invoke.d.ts +0 -3
  339. package/src/generated/orbpro/invoke.js +0 -5
  340. package/src/generated/spacedatastandards/plg/entry-function.js +0 -86
  341. package/src/generated/spacedatastandards/plg/entry-function.ts +0 -119
  342. package/src/generated/spacedatastandards/plg/index.js +0 -16
  343. package/src/generated/spacedatastandards/plg/index.ts +0 -11
  344. package/src/generated/spacedatastandards/plg/plg.js +0 -657
  345. package/src/generated/spacedatastandards/plg/plg.ts +0 -924
  346. package/src/generated/spacedatastandards/plg/plugin-capability.js +0 -66
  347. package/src/generated/spacedatastandards/plg/plugin-category.js +0 -15
  348. package/src/generated/spacedatastandards/plg/plugin-category.ts +0 -53
  349. package/src/generated/spacedatastandards/plg/plugin-dependency.js +0 -63
  350. package/src/generated/spacedatastandards/plg/plugin-dependency.ts +0 -86
  351. package/src/generated/spacedatastandards/plg/publication-state.js +0 -9
  352. package/src/generated/spacedatastandards/plg/purchase-tier.js +0 -9
  353. /package/src/generated/spacedatastandards/plg/{publication-state.ts → publicationState.ts} +0 -0
  354. /package/src/generated/spacedatastandards/plg/{purchase-tier.ts → purchaseTier.ts} +0 -0
@@ -1,13 +1,14 @@
1
1
  import { canonicalBytes } from "../auth/canonicalize.js";
2
+ import * as flatbuffers from "flatbuffers";
3
+ import { KMF, keyMaterialAlgorithm, keyMaterialEncoding, keyMaterialRole } from "spacedatastandards.org/lib/js/KMF/main.js";
2
4
  import {
3
5
  base64ToBytes,
4
6
  bytesToBase64,
7
+ bytesToHex,
5
8
  hexToBytes,
6
9
  toUint8Array,
7
10
  } from "../utils/encoding.js";
8
11
  import {
9
- aesCtrDecrypt,
10
- aesCtrEncrypt,
11
12
  aesGcmDecrypt,
12
13
  aesGcmEncrypt,
13
14
  hkdfBytes,
@@ -19,10 +20,36 @@ import {
19
20
  appendPublicationRecordCollection,
20
21
  createEncryptedEnvelopePayload,
21
22
  decodeEncRecord,
23
+ encodeEncRecord,
22
24
  encodePublicationRecordCollection,
23
25
  extractPublicationRecordCollection,
24
26
  } from "./records.js";
25
27
 
28
+ const GCM_TAG_LENGTH = 16;
29
+
30
+ // The authenticated payload layout is ciphertext || 16-byte GCM tag. The ENC
31
+ // FlatBuffer schema has no dedicated tag field, so the tag travels appended to
32
+ // the ciphertext, mirroring the packed layout already used by the legacy
33
+ // salt-based envelope format.
34
+ function splitGcmPayload(payloadBytes) {
35
+ const payload = toUint8Array(payloadBytes);
36
+ if (payload.length < GCM_TAG_LENGTH) {
37
+ throw new Error("AES-256-GCM protected payload is truncated.");
38
+ }
39
+ return {
40
+ ciphertext: payload.subarray(0, payload.length - GCM_TAG_LENGTH),
41
+ tag: payload.subarray(payload.length - GCM_TAG_LENGTH),
42
+ };
43
+ }
44
+
45
+ function assertGcmEncRecord(enc) {
46
+ if (enc?.symmetric !== "AES_256_GCM") {
47
+ throw new Error(
48
+ `Unsupported ENC symmetric algorithm "${enc?.symmetric}"; only AES_256_GCM is supported.`,
49
+ );
50
+ }
51
+ }
52
+
26
53
  function normalizePublicKey(value) {
27
54
  if (typeof value === "string") {
28
55
  return hexToBytes(value);
@@ -53,6 +80,169 @@ async function deriveAesKey(sharedSecret, salt, context) {
53
80
  );
54
81
  }
55
82
 
83
+ // SAW-M3: the recipient's raw private scalar never has to enter this module.
84
+ // A caller (e.g. a browser session backed by hd-wallet-wasm) may supply a
85
+ // `keyAgreement` provider that performs step 1 (the X25519 ECDH, the ONLY
86
+ // step that needs the scalar) behind its own custody boundary and resolves
87
+ // the 32-byte shared secret. Steps 2-3 (HKDF derive, AES-GCM) stay here —
88
+ // public math, curve-agnostic, not duplicated into the wallet.
89
+ function keyExchangeFromAlgorithm(algorithm) {
90
+ if (typeof algorithm !== "string" || !algorithm.length) {
91
+ return "X25519";
92
+ }
93
+ return algorithm.split("-")[0] || "X25519";
94
+ }
95
+
96
+ async function resolveSharedSecret(
97
+ label,
98
+ { recipientPrivateKey, keyAgreement, ephemeralPublicKey, context, keyExchange },
99
+ ) {
100
+ if (recipientPrivateKey && keyAgreement) {
101
+ throw new Error(
102
+ `${label} accepts either recipientPrivateKey or keyAgreement, not both.`,
103
+ );
104
+ }
105
+ if (keyAgreement) {
106
+ const sharedSecret = toUint8Array(
107
+ await keyAgreement({ ephemeralPublicKey, context, keyExchange }),
108
+ );
109
+ if (sharedSecret.length !== 32) {
110
+ throw new Error(
111
+ `${label} keyAgreement provider must resolve a 32-byte shared secret.`,
112
+ );
113
+ }
114
+ return sharedSecret;
115
+ }
116
+ if (!recipientPrivateKey) {
117
+ throw new Error(`${label} requires recipientPrivateKey or keyAgreement.`);
118
+ }
119
+ return deriveSharedSecret(recipientPrivateKey, ephemeralPublicKey);
120
+ }
121
+
122
+ function normalizeOptionalBytes(value) {
123
+ if (value === null || value === undefined) {
124
+ return new Uint8Array(0);
125
+ }
126
+ if (typeof value === "string") {
127
+ return hexToBytes(value);
128
+ }
129
+ return toUint8Array(value);
130
+ }
131
+
132
+ function normalizeRequiredString(value, name) {
133
+ const normalized = String(value ?? "").trim();
134
+ if (!normalized) {
135
+ throw new Error(`${name} is required.`);
136
+ }
137
+ return normalized;
138
+ }
139
+
140
+ function normalizeArtifactBinding(artifact = {}) {
141
+ const listingId = normalizeRequiredString(artifact.listingId, "artifact.listingId");
142
+ const moduleId = normalizeRequiredString(artifact.moduleId, "artifact.moduleId");
143
+ const version = normalizeRequiredString(artifact.version, "artifact.version");
144
+ const encryptedCid = normalizeRequiredString(
145
+ artifact.encryptedCid,
146
+ "artifact.encryptedCid",
147
+ );
148
+ const providerId = normalizeRequiredString(artifact.providerId, "artifact.providerId");
149
+ const policyId = normalizeRequiredString(artifact.policyId, "artifact.policyId");
150
+ const keyEpoch = normalizeRequiredString(artifact.keyEpoch, "artifact.keyEpoch");
151
+ const contentKeyId =
152
+ String(artifact.contentKeyId ?? "").trim() ||
153
+ `${listingId}:${moduleId}:${version}:${keyEpoch}`;
154
+ const encryptedHash = normalizeOptionalBytes(artifact.encryptedHash);
155
+ if (encryptedHash.length !== 32) {
156
+ throw new Error("artifact.encryptedHash must be 32 bytes.");
157
+ }
158
+ const manifestHash = normalizeOptionalBytes(artifact.manifestHash);
159
+ if (manifestHash.length !== 32) {
160
+ throw new Error("artifact.manifestHash must be 32 bytes.");
161
+ }
162
+ return {
163
+ listingId,
164
+ moduleId,
165
+ version,
166
+ encryptedCid,
167
+ encryptedHash: bytesToHex(encryptedHash),
168
+ providerId,
169
+ policyId,
170
+ keyEpoch,
171
+ manifestHash: bytesToHex(manifestHash),
172
+ contentKeyId,
173
+ };
174
+ }
175
+
176
+ export function createMarketplaceContentAad(artifact = {}) {
177
+ const binding = normalizeArtifactBinding(artifact);
178
+ return canonicalBytes({
179
+ encryptedCid: binding.encryptedCid,
180
+ encryptedHash: binding.encryptedHash,
181
+ keyEpoch: binding.keyEpoch,
182
+ listingId: binding.listingId,
183
+ manifestHash: binding.manifestHash,
184
+ moduleId: binding.moduleId,
185
+ policyId: binding.policyId,
186
+ providerId: binding.providerId,
187
+ version: binding.version,
188
+ });
189
+ }
190
+
191
+ function createWrapAad({ artifact, recipient, algorithm }) {
192
+ return canonicalBytes({
193
+ algorithm,
194
+ contentKeyId: artifact.contentKeyId,
195
+ encryptedCid: artifact.encryptedCid,
196
+ expiresAtMs: Number(recipient.expiresAtMs ?? 0),
197
+ grantId: normalizeRequiredString(recipient.grantId, "recipient.grantId"),
198
+ keyEpoch: artifact.keyEpoch,
199
+ providerId: artifact.providerId,
200
+ recipientKeyId: normalizeRequiredString(
201
+ recipient.recipientKeyId,
202
+ "recipient.recipientKeyId",
203
+ ),
204
+ scope: normalizeRequiredString(recipient.scope, "recipient.scope"),
205
+ });
206
+ }
207
+
208
+ function encodeContentKeyMaterial({ keyId, keyBytes, expiresAtMs }) {
209
+ const builder = new flatbuffers.Builder(256);
210
+ const keyIdOffset = builder.createString(keyId);
211
+ const keyBytesOffset = KMF.createKeyBytesVector(builder, keyBytes);
212
+ const root = KMF.createKMF(
213
+ builder,
214
+ keyIdOffset,
215
+ keyMaterialRole.PublicationContent,
216
+ keyMaterialAlgorithm.Aes256Gcm,
217
+ keyMaterialEncoding.RawBytes,
218
+ keyBytesOffset,
219
+ 1,
220
+ BigInt(Number(expiresAtMs ?? 0)),
221
+ );
222
+ KMF.finishKMFBuffer(builder, root);
223
+ return builder.asUint8Array();
224
+ }
225
+
226
+ function decodeContentKeyMaterial(bytes) {
227
+ const payload = toUint8Array(bytes);
228
+ const bb = new flatbuffers.ByteBuffer(payload);
229
+ if (!KMF.bufferHasIdentifier(bb)) {
230
+ throw new Error("Wrapped marketplace content key payload is not a KMF record.");
231
+ }
232
+ const kmf = KMF.getRootAsKMF(bb);
233
+ if (kmf.ROLE() !== keyMaterialRole.PublicationContent) {
234
+ throw new Error("Wrapped marketplace key material is not a publication content key.");
235
+ }
236
+ if (kmf.ALGORITHM() !== keyMaterialAlgorithm.Aes256Gcm) {
237
+ throw new Error("Wrapped marketplace key material is not an AES-256-GCM key.");
238
+ }
239
+ const keyBytes = kmf.keyBytesArray();
240
+ if (!keyBytes || keyBytes.length !== 32) {
241
+ throw new Error("Wrapped marketplace content key must be 32 bytes.");
242
+ }
243
+ return new Uint8Array(keyBytes);
244
+ }
245
+
56
246
  export async function generateX25519Keypair() {
57
247
  const privateKey = await randomBytes(32);
58
248
  const publicKey = await x25519PublicKey(privateKey);
@@ -62,6 +252,128 @@ export async function generateX25519Keypair() {
62
252
  };
63
253
  }
64
254
 
255
+ export async function protectMarketplaceContent({
256
+ plaintext,
257
+ artifact,
258
+ recipients = [],
259
+ contentKey = null,
260
+ contentNonce = null,
261
+ providerWrapKeyPair = null,
262
+ wrapNonce = null,
263
+ } = {}) {
264
+ if (!Array.isArray(recipients) || recipients.length === 0) {
265
+ throw new Error("protectMarketplaceContent requires at least one recipient.");
266
+ }
267
+ const binding = normalizeArtifactBinding(artifact);
268
+ const keyBytes = contentKey ? toUint8Array(contentKey) : await randomBytes(32);
269
+ if (keyBytes.length !== 32) {
270
+ throw new Error("Marketplace content keys must be 32 bytes.");
271
+ }
272
+ const nonce = contentNonce ? toUint8Array(contentNonce) : await randomBytes(12);
273
+ if (nonce.length !== 12) {
274
+ throw new Error("AES-256-GCM content encryption requires a 12-byte nonce.");
275
+ }
276
+ const aad = createMarketplaceContentAad(binding);
277
+ const encrypted = await aesGcmEncrypt(
278
+ keyBytes,
279
+ toUint8Array(plaintext),
280
+ nonce,
281
+ aad,
282
+ );
283
+ const wrappedKeys = [];
284
+ for (const recipient of recipients) {
285
+ const sender = providerWrapKeyPair ?? (await generateX25519Keypair());
286
+ const recipientPublicKey = normalizePublicKey(recipient.publicKey);
287
+ const wrapIv = wrapNonce ? toUint8Array(wrapNonce) : await randomBytes(12);
288
+ if (wrapIv.length !== 12) {
289
+ throw new Error("AES-256-GCM key wrapping requires a 12-byte nonce.");
290
+ }
291
+ const wrapAad = createWrapAad({
292
+ artifact: binding,
293
+ recipient,
294
+ algorithm: "X25519-HKDF-SHA256-AES-256-GCM-KMF",
295
+ });
296
+ const sharedSecret = await deriveSharedSecret(
297
+ sender.privateKey,
298
+ recipientPublicKey,
299
+ );
300
+ const wrapContext = `marketplace-content-key:${binding.providerId}:${binding.contentKeyId}:${recipient.recipientKeyId}`;
301
+ const wrapKey = await deriveAesKey(sharedSecret, new Uint8Array(0), wrapContext);
302
+ const keyMaterial = encodeContentKeyMaterial({
303
+ keyId: binding.contentKeyId,
304
+ keyBytes,
305
+ expiresAtMs: recipient.expiresAtMs,
306
+ });
307
+ const wrapped = await aesGcmEncrypt(wrapKey, keyMaterial, wrapIv, wrapAad);
308
+ wrappedKeys.push({
309
+ algorithm: "X25519-HKDF-SHA256-AES-256-GCM-KMF",
310
+ contentKeyId: binding.contentKeyId,
311
+ recipientPeerId: normalizeRequiredString(
312
+ recipient.recipientPeerId,
313
+ "recipient.recipientPeerId",
314
+ ),
315
+ recipientKeyId: normalizeRequiredString(
316
+ recipient.recipientKeyId,
317
+ "recipient.recipientKeyId",
318
+ ),
319
+ providerId: binding.providerId,
320
+ encryptedCid: binding.encryptedCid,
321
+ grantId: normalizeRequiredString(recipient.grantId, "recipient.grantId"),
322
+ scope: normalizeRequiredString(recipient.scope, "recipient.scope"),
323
+ expiresAtMs: Number(recipient.expiresAtMs ?? 0),
324
+ providerEphemeralPublicKey: sender.publicKey,
325
+ nonce: wrapIv,
326
+ aad: wrapAad,
327
+ ciphertext: wrapped.ciphertext,
328
+ tag: wrapped.tag,
329
+ });
330
+ }
331
+ return {
332
+ algorithm: "AES-256-GCM",
333
+ contentKeyId: binding.contentKeyId,
334
+ artifact: binding,
335
+ aad,
336
+ encryptedPayload: {
337
+ algorithm: "AES-256-GCM",
338
+ nonce,
339
+ aad,
340
+ ciphertext: encrypted.ciphertext,
341
+ tag: encrypted.tag,
342
+ },
343
+ wrappedKeys,
344
+ };
345
+ }
346
+
347
+ export async function decryptMarketplaceContentKeyWrap({
348
+ wrap,
349
+ recipientPrivateKey,
350
+ keyAgreement,
351
+ } = {}) {
352
+ if (!wrap) {
353
+ throw new Error("decryptMarketplaceContentKeyWrap requires wrap.");
354
+ }
355
+ const wrapContext = `marketplace-content-key:${wrap.providerId}:${wrap.contentKeyId}:${wrap.recipientKeyId}`;
356
+ const sharedSecret = await resolveSharedSecret(
357
+ "decryptMarketplaceContentKeyWrap",
358
+ {
359
+ recipientPrivateKey,
360
+ keyAgreement,
361
+ ephemeralPublicKey: wrap.providerEphemeralPublicKey,
362
+ context: wrapContext,
363
+ keyExchange: keyExchangeFromAlgorithm(wrap.algorithm),
364
+ },
365
+ );
366
+ const wrapKey = await deriveAesKey(sharedSecret, new Uint8Array(0), wrapContext);
367
+ const keyMaterial = await aesGcmDecrypt(
368
+ wrapKey,
369
+ wrap.ciphertext,
370
+ wrap.tag,
371
+ wrap.nonce,
372
+ wrap.aad,
373
+ );
374
+ return decodeContentKeyMaterial(keyMaterial);
375
+ }
376
+
65
377
  async function encryptBytesLegacy({
66
378
  plaintext,
67
379
  recipientPublicKey,
@@ -98,21 +410,33 @@ async function encryptBytesLegacy({
98
410
  export async function decryptProtectedBytes({
99
411
  protectedBytes,
100
412
  recipientPrivateKey,
413
+ keyAgreement,
101
414
  } = {}) {
102
415
  const parsed = extractPublicationRecordCollection(protectedBytes);
103
416
  if (!parsed?.enc) {
104
417
  return toUint8Array(protectedBytes);
105
418
  }
106
- const sharedSecret = await deriveSharedSecret(
419
+ assertGcmEncRecord(parsed.enc);
420
+ const sharedSecret = await resolveSharedSecret("decryptProtectedBytes", {
107
421
  recipientPrivateKey,
108
- parsed.enc.ephemeralPublicKey,
109
- );
422
+ keyAgreement,
423
+ ephemeralPublicKey: parsed.enc.ephemeralPublicKey,
424
+ context: parsed.enc.context ?? "",
425
+ keyExchange: parsed.enc.keyExchange,
426
+ });
110
427
  const aesKey = await deriveAesKey(
111
428
  sharedSecret,
112
429
  new Uint8Array(0),
113
430
  parsed.enc.context ?? "",
114
431
  );
115
- return aesCtrDecrypt(aesKey, parsed.payloadBytes, parsed.enc.nonceStart);
432
+ const { ciphertext, tag } = splitGcmPayload(parsed.payloadBytes);
433
+ return aesGcmDecrypt(
434
+ aesKey,
435
+ ciphertext,
436
+ tag,
437
+ parsed.enc.nonceStart,
438
+ encodeEncRecord(parsed.enc),
439
+ );
116
440
  }
117
441
 
118
442
  export async function encryptBytesForRecipient({
@@ -134,11 +458,10 @@ export async function encryptBytesForRecipient({
134
458
  recipientPublicKey,
135
459
  );
136
460
  const aesKey = await deriveAesKey(sharedSecret, new Uint8Array(0), context);
137
- const ciphertext = await aesCtrEncrypt(aesKey, toUint8Array(plaintext), nonceStart);
138
461
  const enc = {
139
462
  version: 1,
140
463
  keyExchange: "X25519",
141
- symmetric: "AES_256_CTR",
464
+ symmetric: "AES_256_GCM",
142
465
  keyDerivation: "HKDF_SHA256",
143
466
  ephemeralPublicKey: sender.publicKey,
144
467
  nonceStart,
@@ -148,15 +471,29 @@ export async function encryptBytesForRecipient({
148
471
  rootType,
149
472
  timestamp: Date.now(),
150
473
  };
474
+ // The encoded ENC record doubles as the GCM AAD so every delivery parameter
475
+ // (context, schema hash, root type, recipient key id, nonce, ephemeral key)
476
+ // is authenticated alongside the ciphertext. encodeEncRecord() is
477
+ // deterministic for a normalized record, so decrypt paths recompute the
478
+ // identical bytes from the parsed ENC record.
479
+ const { ciphertext, tag } = await aesGcmEncrypt(
480
+ aesKey,
481
+ toUint8Array(plaintext),
482
+ nonceStart,
483
+ encodeEncRecord(enc),
484
+ );
485
+ const payloadBytes = new Uint8Array(ciphertext.length + tag.length);
486
+ payloadBytes.set(ciphertext, 0);
487
+ payloadBytes.set(tag, ciphertext.length);
151
488
  const recordCollectionBytes = encodePublicationRecordCollection({ enc });
152
489
  const protectedBlobBytes = appendPublicationRecordCollection(
153
- ciphertext,
490
+ payloadBytes,
154
491
  recordCollectionBytes,
155
492
  );
156
493
  return createEncryptedEnvelopePayload({
157
494
  protectedBlobBytes,
158
495
  parsedProtectedBlob: {
159
- payloadBytes: ciphertext,
496
+ payloadBytes,
160
497
  recordCollectionBytes,
161
498
  enc,
162
499
  pnm: null,
@@ -182,7 +519,9 @@ export async function decryptBytesFromEnvelope({
182
519
  });
183
520
  }
184
521
  if (envelope.ciphertextBase64 && envelope.encRecordBase64) {
185
- const enc = decodeEncRecord(base64ToBytes(envelope.encRecordBase64));
522
+ const encRecordBytes = base64ToBytes(envelope.encRecordBase64);
523
+ const enc = decodeEncRecord(encRecordBytes);
524
+ assertGcmEncRecord(enc);
186
525
  const sharedSecret = await deriveSharedSecret(
187
526
  recipientPrivateKey,
188
527
  enc.ephemeralPublicKey,
@@ -192,11 +531,10 @@ export async function decryptBytesFromEnvelope({
192
531
  new Uint8Array(0),
193
532
  enc.context ?? envelope.context ?? "",
194
533
  );
195
- return aesCtrDecrypt(
196
- aesKey,
534
+ const { ciphertext, tag } = splitGcmPayload(
197
535
  base64ToBytes(envelope.ciphertextBase64),
198
- enc.nonceStart,
199
536
  );
537
+ return aesGcmDecrypt(aesKey, ciphertext, tag, enc.nonceStart, encRecordBytes);
200
538
  }
201
539
  const sharedSecret = await deriveSharedSecret(
202
540
  recipientPrivateKey,
@@ -40,8 +40,14 @@ const KEY_EXCHANGE_NAME_BY_VALUE = Object.freeze(
40
40
  Object.entries(KEY_EXCHANGE_BY_NAME).map(([name, value]) => [value, name]),
41
41
  ),
42
42
  );
43
+ // AES_256_GCM is not yet published in the spacedatastandards.org generated
44
+ // SymmetricAlgo enum (which only defines AES_256_CTR = 0). The SYMMETRIC field
45
+ // is a plain byte on the wire, so value 1 is encoded directly until the schema
46
+ // publishes the enum member.
47
+ const SYMMETRIC_ALGO_AES_256_GCM = 1;
43
48
  const SYMMETRIC_ALGO_BY_NAME = Object.freeze({
44
49
  AES_256_CTR: SymmetricAlgo.AES_256_CTR,
50
+ AES_256_GCM: SYMMETRIC_ALGO_AES_256_GCM,
45
51
  });
46
52
  const SYMMETRIC_ALGO_NAME_BY_VALUE = Object.freeze(
47
53
  Object.fromEntries(
@@ -429,12 +435,15 @@ function normalizeSymmetricAlgorithm(value) {
429
435
  if (typeof value === "number") {
430
436
  return value;
431
437
  }
432
- return SYMMETRIC_ALGO_BY_NAME[
433
- String(value ?? "AES_256_CTR")
434
- .trim()
435
- .replace(/[^A-Za-z0-9]+/g, "_")
436
- .toUpperCase()
437
- ] ?? SymmetricAlgo.AES_256_CTR;
438
+ const normalized = String(value ?? "AES_256_GCM")
439
+ .trim()
440
+ .replace(/[^A-Za-z0-9]+/g, "_")
441
+ .toUpperCase();
442
+ const resolved = SYMMETRIC_ALGO_BY_NAME[normalized];
443
+ if (resolved === undefined) {
444
+ throw new Error(`Unsupported ENC symmetric algorithm "${value}".`);
445
+ }
446
+ return resolved;
438
447
  }
439
448
 
440
449
  function normalizeKdf(value) {
@@ -834,7 +843,7 @@ export function createEncryptedEnvelopePayload(options = {}) {
834
843
  const envelope = {
835
844
  version: Number(options.version ?? 2),
836
845
  scheme:
837
- normalizeStringField(options.scheme) ?? "x25519-hkdf-aes-256-ctr-rec",
846
+ normalizeStringField(options.scheme) ?? "x25519-hkdf-aes-256-gcm-rec",
838
847
  context: normalizeStringField(options.context ?? enc?.context) ?? "",
839
848
  protectedBlobBase64: bytesToBase64(protectedBlob),
840
849
  recordCollectionBase64: parsed
@@ -0,0 +1,106 @@
1
+ /**
2
+ * DER <-> raw conversion for secp256k1 ECDSA signatures.
3
+ *
4
+ * The shared WASM crypto backend (hd-wallet-wasm) produces and consumes
5
+ * raw 64-byte (r || s) signatures. EPM SIGNATURE bytes, however, are
6
+ * ECDSA-DER encoded (SEQUENCE { INTEGER r, INTEGER s }). These helpers
7
+ * bridge the two encodings so the host-crypto ABI can honor the DER
8
+ * contract while calling the raw-signature WASM primitives.
9
+ */
10
+
11
+ import { toUint8Array } from "./encoding.js";
12
+
13
+ const RAW_SIGNATURE_LENGTH = 64;
14
+ const COMPONENT_LENGTH = 32;
15
+
16
+ function encodeDerInteger(component) {
17
+ // Strip superfluous leading zero bytes, keeping at least one byte.
18
+ let start = 0;
19
+ while (start < component.length - 1 && component[start] === 0) {
20
+ start += 1;
21
+ }
22
+ let value = component.subarray(start);
23
+ // DER integers are signed; prepend 0x00 when the high bit is set so the
24
+ // value is not interpreted as negative.
25
+ if ((value[0] & 0x80) !== 0) {
26
+ const padded = new Uint8Array(value.length + 1);
27
+ padded.set(value, 1);
28
+ value = padded;
29
+ }
30
+ const encoded = new Uint8Array(value.length + 2);
31
+ encoded[0] = 0x02; // INTEGER
32
+ encoded[1] = value.length;
33
+ encoded.set(value, 2);
34
+ return encoded;
35
+ }
36
+
37
+ /**
38
+ * Encode a raw 64-byte (r || s) secp256k1 ECDSA signature as DER.
39
+ */
40
+ export function rawSignatureToDer(rawSignature) {
41
+ const bytes = toUint8Array(rawSignature);
42
+ if (bytes.length !== RAW_SIGNATURE_LENGTH) {
43
+ throw new Error(
44
+ `secp256k1 raw signature must be ${RAW_SIGNATURE_LENGTH} bytes, received ${bytes.length}.`,
45
+ );
46
+ }
47
+ const r = encodeDerInteger(bytes.subarray(0, COMPONENT_LENGTH));
48
+ const s = encodeDerInteger(bytes.subarray(COMPONENT_LENGTH, RAW_SIGNATURE_LENGTH));
49
+ const body = new Uint8Array(r.length + s.length);
50
+ body.set(r, 0);
51
+ body.set(s, r.length);
52
+ // Signature bodies never exceed 127 bytes, so short-form length is safe.
53
+ const der = new Uint8Array(body.length + 2);
54
+ der[0] = 0x30; // SEQUENCE
55
+ der[1] = body.length;
56
+ der.set(body, 2);
57
+ return der;
58
+ }
59
+
60
+ function normalizeComponent(component) {
61
+ let start = 0;
62
+ while (start < component.length - 1 && component[start] === 0) {
63
+ start += 1;
64
+ }
65
+ const value = component.subarray(start);
66
+ if (value.length > COMPONENT_LENGTH) {
67
+ throw new Error("Invalid DER signature: integer component exceeds 32 bytes.");
68
+ }
69
+ const out = new Uint8Array(COMPONENT_LENGTH);
70
+ out.set(value, COMPONENT_LENGTH - value.length);
71
+ return out;
72
+ }
73
+
74
+ function readDerInteger(bytes, offset) {
75
+ if (bytes[offset] !== 0x02) {
76
+ throw new Error("Invalid DER signature: expected INTEGER.");
77
+ }
78
+ const length = bytes[offset + 1];
79
+ const start = offset + 2;
80
+ const end = start + length;
81
+ if (end > bytes.length) {
82
+ throw new Error("Invalid DER signature: INTEGER length exceeds bounds.");
83
+ }
84
+ return { value: bytes.subarray(start, end), next: end };
85
+ }
86
+
87
+ /**
88
+ * Decode a DER-encoded secp256k1 ECDSA signature into raw 64-byte (r || s).
89
+ */
90
+ export function derSignatureToRaw(derSignature) {
91
+ const bytes = toUint8Array(derSignature);
92
+ if (bytes.length < 8 || bytes[0] !== 0x30) {
93
+ throw new Error("Invalid DER signature: expected SEQUENCE.");
94
+ }
95
+ let offset = 2;
96
+ if ((bytes[1] & 0x80) !== 0) {
97
+ // Long-form length; skip the length-of-length bytes.
98
+ offset = 2 + (bytes[1] & 0x7f);
99
+ }
100
+ const rPart = readDerInteger(bytes, offset);
101
+ const sPart = readDerInteger(bytes, rPart.next);
102
+ const raw = new Uint8Array(RAW_SIGNATURE_LENGTH);
103
+ raw.set(normalizeComponent(rPart.value), 0);
104
+ raw.set(normalizeComponent(sPart.value), COMPONENT_LENGTH);
105
+ return raw;
106
+ }
@@ -116,46 +116,3 @@ export async function aesGcmDecrypt(key, ciphertext, tag, iv, aad = null) {
116
116
  aad ? toUint8Array(aad) : undefined,
117
117
  );
118
118
  }
119
-
120
- function normalizeCtrIv(nonceStart) {
121
- const nonce = toUint8Array(nonceStart);
122
- if (nonce.length !== 12) {
123
- throw new Error("AES-256-CTR expects a 12-byte NONCE_START value.");
124
- }
125
- const iv = new Uint8Array(16);
126
- iv.set(nonce, 0);
127
- return iv;
128
- }
129
-
130
- async function getAesCtrApi() {
131
- const wallet = await getWasmWallet();
132
- const aesCtr = wallet?.aesCtr;
133
- if (
134
- !aesCtr ||
135
- typeof aesCtr.encrypt !== "function" ||
136
- typeof aesCtr.decrypt !== "function"
137
- ) {
138
- throw new Error(
139
- "hd-wallet-wasm aesCtr API is unavailable; cannot process ENC payloads.",
140
- );
141
- }
142
- return aesCtr;
143
- }
144
-
145
- export async function aesCtrEncrypt(key, plaintext, nonceStart) {
146
- const aesCtr = await getAesCtrApi();
147
- return aesCtr.encrypt(
148
- toUint8Array(key),
149
- toUint8Array(plaintext),
150
- normalizeCtrIv(nonceStart),
151
- );
152
- }
153
-
154
- export async function aesCtrDecrypt(key, ciphertext, nonceStart) {
155
- const aesCtr = await getAesCtrApi();
156
- return aesCtr.decrypt(
157
- toUint8Array(key),
158
- toUint8Array(ciphertext),
159
- normalizeCtrIv(nonceStart),
160
- );
161
- }
@@ -0,0 +1,48 @@
1
+ # GPU Module Template
2
+
3
+ This template is the SDK starting point for modules that can use WebGPU in the
4
+ browser and Dawn in a native WasmEdge host while keeping a portable CPU
5
+ fallback.
6
+
7
+ ## Files
8
+
9
+ - `include/space_data_gpu_abi.h`: shared C/C++ layout ABI for GPU-capable
10
+ module code and host adapters.
11
+ - `manifest.json`: starter manifest showing the `gpu_compute` capability.
12
+
13
+ ## Runtime Shape
14
+
15
+ Keep the canonical module artifact at:
16
+
17
+ ```text
18
+ dist/isomorphic/module.wasm
19
+ ```
20
+
21
+ That artifact must run without GPU access. Put optional GPU adapters beside it:
22
+
23
+ ```text
24
+ dist/browser/module.js
25
+ dist/wasmedge/gpu-host.{so,dylib,dll}
26
+ ```
27
+
28
+ The browser adapter owns WebGPU. The WasmEdge host extension owns Dawn. The
29
+ module owns correctness, fallback, and final result validation.
30
+
31
+ ## C++ Integration
32
+
33
+ Include the ABI header from module or host code:
34
+
35
+ ```cpp
36
+ #include "space_data_gpu_abi.h"
37
+ ```
38
+
39
+ Use `SdnGpuSplitF64` for double-like values that must cross into WGSL as two
40
+ `f32` values:
41
+
42
+ ```cpp
43
+ SdnGpuVec3SplitF64 position = sdn_gpu_split_vec3_f64(x_km, y_km, z_km);
44
+ ```
45
+
46
+ Use the dispatch/result descriptor structs for host adapter boundaries. Do not
47
+ store raw pointers in manifests, publication metadata, or durable runtime
48
+ records.