space-data-module-sdk 0.8.4 → 0.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +117 -20
- package/bin/space-data-module.js +263 -0
- package/docs/.nojekyll +1 -0
- package/docs/AGENTS.md +34 -0
- package/docs/architecture.svg +141 -0
- package/docs/browser-wasmedge-isomorphic.md +179 -0
- package/docs/flatsql-streaming-standard.md +341 -0
- package/docs/gpu-module-abi.md +193 -0
- package/docs/index.html +125 -0
- package/docs/isomorphic-pthreads.md +188 -0
- package/docs/isomorphic-sdn-runtime-plan.md +167 -0
- package/docs/language-runtime-matrix.md +82 -0
- package/docs/manifest-structure.svg +114 -0
- package/docs/module-bundle-runtime-plan.md +19 -0
- package/docs/module-lifecycle.svg +70 -0
- package/docs/module-publication-standard.md +540 -0
- package/docs/node-red-default-node-parity.md +88 -0
- package/docs/protocol-installation.md +196 -0
- package/docs/secrets-capability.md +152 -0
- package/docs/styles.css +288 -0
- package/docs/testing-harness.md +408 -0
- package/docs/tri-runtime-parity.md +132 -0
- package/docs/wallet-callback.html +2 -0
- package/package.json +25 -6
- package/schemas/HttpRequestAbi.fbs +41 -0
- package/schemas/HttpResponseAbi.fbs +36 -0
- package/schemas/PluginManifest.fbs +2 -1
- package/src/AGENTS.md +1 -1
- package/src/app/codec.js +548 -0
- package/src/app/index.js +6 -0
- package/src/browser.js +5 -0
- package/src/bundle/constants.js +1 -0
- package/src/bundle/index.js +15 -0
- package/src/bundle/sigdomain.js +179 -0
- package/src/bundle/signing.js +767 -0
- package/src/bundle/wasm.js +3 -2
- package/src/capabilities.js +3 -0
- package/src/compat/index.js +7 -0
- package/src/compat/sdnLegacy.js +449 -0
- package/src/compiler/compileModule.js +556 -55
- package/src/compiler/flatcSupport.js +41 -27
- package/src/compiler/index.d.ts +2 -0
- package/src/compiler/index.js +18 -0
- package/src/compiler/invokeGlue.js +1212 -183
- package/src/compiler/pthreadArtifactGuard.js +910 -0
- package/src/compiler/sdnShimGenerator.js +323 -0
- package/src/compiler/wasiThreadsToolchain.js +150 -0
- package/src/compliance/index.js +11 -1
- package/src/compliance/legacyWildcardPorts.js +228 -0
- package/src/compliance/pluginCompliance.js +1000 -96
- package/src/field-stream/index.d.ts +31 -0
- package/src/field-stream/index.js +119 -0
- package/src/flow/dependencyStreamBridge.js +234 -0
- package/src/flow/flatsqlLinkShim.js +304 -0
- package/src/flow/flowCodec.js +107 -0
- package/src/flow/flowCompiler.js +2900 -0
- package/src/flow/flowRuntimeHost.js +877 -0
- package/src/flow/index.d.ts +117 -0
- package/src/flow/index.js +31 -0
- package/src/flow/isomorphicFlowHost.js +384 -0
- package/src/flow/jsFlowRuntime.js +275 -0
- package/src/flow/normalize.js +294 -0
- package/src/flow/runtime-src/flow_runtime.cpp +1699 -0
- package/src/flow/vendor/sdn-flow/MethodRegistry.js +400 -0
- package/src/flow/vendor/sdn-flow/constants.js +39 -0
- package/src/flow/vendor/sdn-flow/index.js +29 -0
- package/src/flow/vendor/sdn-flow/normalize.js +506 -0
- package/src/flow/vendor/sdn-flow/wasmCompatibility.js +189 -0
- package/src/generated/http/cpp/HttpRequestAbi_generated.h +285 -0
- package/src/generated/http/cpp/HttpResponseAbi_generated.h +192 -0
- package/src/generated/http/sdn/http/http-header.js +53 -0
- package/src/generated/http/sdn/http/http-header.ts +67 -0
- package/src/generated/http/sdn/http/http-request.js +132 -0
- package/src/generated/http/sdn/http/http-request.ts +179 -0
- package/src/generated/http/sdn/http/http-response.js +144 -0
- package/src/generated/http/sdn/http/http-response.ts +168 -0
- package/src/generated/http/sdn/http.js +11 -0
- package/src/generated/http/sdn/http.ts +4 -0
- package/src/generated/orbpro/flow/backpressure-policy.d.ts +12 -0
- package/src/generated/orbpro/flow/backpressure-policy.d.ts.map +1 -0
- package/src/generated/orbpro/flow/backpressure-policy.js +17 -0
- package/src/generated/orbpro/flow/backpressure-policy.js.map +1 -0
- package/src/generated/orbpro/flow/backpressure-policy.ts +15 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts +142 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.js +304 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.js.map +1 -0
- package/src/generated/orbpro/flow/flow-bundle-manifest.ts +399 -0
- package/src/generated/orbpro/flow/flow-edge.d.ts +113 -0
- package/src/generated/orbpro/flow/flow-edge.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-edge.js +221 -0
- package/src/generated/orbpro/flow/flow-edge.js.map +1 -0
- package/src/generated/orbpro/flow/flow-edge.ts +292 -0
- package/src/generated/orbpro/flow/flow-node.d.ts +80 -0
- package/src/generated/orbpro/flow/flow-node.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-node.js +158 -0
- package/src/generated/orbpro/flow/flow-node.js.map +1 -0
- package/src/generated/orbpro/flow/flow-node.ts +202 -0
- package/src/generated/orbpro/flow/flow-program.d.ts +164 -0
- package/src/generated/orbpro/flow/flow-program.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-program.js +350 -0
- package/src/generated/orbpro/flow/flow-program.js.map +1 -0
- package/src/generated/orbpro/flow/flow-program.ts +477 -0
- package/src/generated/orbpro/flow/flow-trigger.d.ts +108 -0
- package/src/generated/orbpro/flow/flow-trigger.d.ts.map +1 -0
- package/src/generated/orbpro/flow/flow-trigger.js +207 -0
- package/src/generated/orbpro/flow/flow-trigger.js.map +1 -0
- package/src/generated/orbpro/flow/flow-trigger.ts +276 -0
- package/src/generated/orbpro/flow/node-kind.d.ts +13 -0
- package/src/generated/orbpro/flow/node-kind.d.ts.map +1 -0
- package/src/generated/orbpro/flow/node-kind.js +16 -0
- package/src/generated/orbpro/flow/node-kind.js.map +1 -0
- package/src/generated/orbpro/{invoke.ts → flow/node-kind.ts} +12 -2
- package/src/generated/orbpro/flow/plugin-version-binding.d.ts +52 -0
- package/src/generated/orbpro/flow/plugin-version-binding.d.ts.map +1 -0
- package/src/generated/orbpro/flow/plugin-version-binding.js +85 -0
- package/src/generated/orbpro/flow/plugin-version-binding.js.map +1 -0
- package/src/generated/orbpro/flow/plugin-version-binding.ts +121 -0
- package/src/generated/orbpro/flow/schema-hash-binding.d.ts +70 -0
- package/src/generated/orbpro/flow/schema-hash-binding.d.ts.map +1 -0
- package/src/generated/orbpro/flow/schema-hash-binding.js +143 -0
- package/src/generated/orbpro/flow/schema-hash-binding.js.map +1 -0
- package/src/generated/orbpro/flow/schema-hash-binding.ts +189 -0
- package/src/generated/orbpro/flow/trigger-binding.d.ts +71 -0
- package/src/generated/orbpro/flow/trigger-binding.d.ts.map +1 -0
- package/src/generated/orbpro/flow/trigger-binding.js +142 -0
- package/src/generated/orbpro/flow/trigger-binding.js.map +1 -0
- package/src/generated/orbpro/flow/trigger-binding.ts +181 -0
- package/src/generated/orbpro/flow/trigger-kind.d.ts +14 -0
- package/src/generated/orbpro/flow/trigger-kind.d.ts.map +1 -0
- package/src/generated/orbpro/flow/trigger-kind.js +17 -0
- package/src/generated/orbpro/flow/trigger-kind.js.map +1 -0
- package/src/generated/orbpro/flow/trigger-kind.ts +17 -0
- package/src/generated/orbpro/flow.d.ts +21 -0
- package/src/generated/orbpro/flow.d.ts.map +1 -0
- package/src/generated/orbpro/flow.js +23 -0
- package/src/generated/orbpro/flow.js.map +1 -0
- package/src/generated/orbpro/flow.ts +24 -0
- package/src/generated/orbpro/manifest/capability-kind.d.ts +2 -1
- package/src/generated/orbpro/manifest/capability-kind.js +1 -0
- package/src/generated/orbpro/manifest/capability-kind.ts +1 -0
- package/src/generated/orbpro/plugin/stream-invoke-request.d.ts +93 -0
- package/src/generated/orbpro/plugin/stream-invoke-request.js +160 -0
- package/src/generated/orbpro/plugin/stream-invoke-request.ts +211 -0
- package/src/generated/orbpro/plugin/stream-invoke-response.d.ts +99 -0
- package/src/generated/orbpro/plugin/stream-invoke-response.js +175 -0
- package/src/generated/orbpro/plugin/stream-invoke-response.ts +226 -0
- package/src/generated/orbpro/plugin.js +8 -0
- package/src/generated/orbpro/stream.d.ts +12 -0
- package/src/generated/orbpro/stream.js +14 -0
- package/src/generated/orbpro/stream.ts +15 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.d.ts +52 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.js +106 -0
- package/src/generated/spacedatastandards/plg/EntryFunction.ts +162 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts +90 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.js +189 -0
- package/src/generated/spacedatastandards/plg/FlatBufferTypeRef.ts +270 -0
- package/src/generated/spacedatastandards/plg/PLG.d.ts +492 -0
- package/src/generated/spacedatastandards/plg/PLG.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLG.js +1139 -0
- package/src/generated/spacedatastandards/plg/PLG.ts +1600 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts +63 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.js +138 -0
- package/src/generated/spacedatastandards/plg/PLGAcceptedTypeSet.ts +189 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts +41 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.js +104 -0
- package/src/generated/spacedatastandards/plg/PLGBuildArtifact.ts +151 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts +68 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.js +124 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdge.ts +184 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts +58 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.js +126 -0
- package/src/generated/spacedatastandards/plg/PLGFlowEdgeContract.ts +161 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts +82 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.js +164 -0
- package/src/generated/spacedatastandards/plg/PLGFlowNode.ts +244 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts +55 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.js +105 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTrigger.ts +162 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts +42 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.js +83 -0
- package/src/generated/spacedatastandards/plg/PLGFlowTriggerBinding.ts +127 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts +36 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.js +90 -0
- package/src/generated/spacedatastandards/plg/PLGHostCapability.ts +127 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts +53 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.js +153 -0
- package/src/generated/spacedatastandards/plg/PLGMethodManifest.ts +210 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts +70 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.js +149 -0
- package/src/generated/spacedatastandards/plg/PLGPortManifest.ts +212 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts +73 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.js +199 -0
- package/src/generated/spacedatastandards/plg/PLGProtocolSpec.ts +292 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts +40 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.js +103 -0
- package/src/generated/spacedatastandards/plg/PLGTimerSpec.ts +148 -0
- package/src/generated/spacedatastandards/plg/PluginCapability.d.ts +41 -0
- package/src/generated/spacedatastandards/plg/PluginCapability.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PluginCapability.js +82 -0
- package/src/generated/spacedatastandards/plg/{plugin-capability.ts → PluginCapability.ts} +55 -18
- package/src/generated/spacedatastandards/plg/PluginDependency.d.ts +42 -0
- package/src/generated/spacedatastandards/plg/PluginDependency.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/PluginDependency.js +80 -0
- package/src/generated/spacedatastandards/plg/PluginDependency.ts +124 -0
- package/src/generated/spacedatastandards/plg/TAB.d.ts +85 -0
- package/src/generated/spacedatastandards/plg/TAB.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/TAB.js +173 -0
- package/src/generated/spacedatastandards/plg/TAB.ts +228 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.js +20 -0
- package/src/generated/spacedatastandards/plg/bufferMutability.ts +23 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.js +20 -0
- package/src/generated/spacedatastandards/plg/bufferOwnership.ts +23 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.d.ts +20 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.js +22 -0
- package/src/generated/spacedatastandards/plg/drainBehavior.ts +25 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts +10 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.js +12 -0
- package/src/generated/spacedatastandards/plg/flowEdgeRoutePolicy.ts +13 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts +51 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.js +53 -0
- package/src/generated/spacedatastandards/plg/hostCapabilityKind.ts +55 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts +15 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.js +17 -0
- package/src/generated/spacedatastandards/plg/invokeSurfaceKind.ts +19 -0
- package/src/generated/spacedatastandards/plg/main.d.ts +29 -0
- package/src/generated/spacedatastandards/plg/main.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/main.js +30 -0
- package/src/generated/spacedatastandards/plg/main.ts +32 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts +17 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.js +19 -0
- package/src/generated/spacedatastandards/plg/payloadWireFormat.ts +21 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.d.ts +82 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.js +84 -0
- package/src/generated/spacedatastandards/plg/pluginCategory.ts +103 -0
- package/src/generated/spacedatastandards/plg/publicationState.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/publicationState.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/publicationState.js +20 -0
- package/src/generated/spacedatastandards/plg/purchaseTier.d.ts +18 -0
- package/src/generated/spacedatastandards/plg/purchaseTier.d.ts.map +1 -0
- package/src/generated/spacedatastandards/plg/purchaseTier.js +20 -0
- package/src/host/AGENTS.md +2 -2
- package/src/host/abi.js +53 -66
- package/src/host/browserHost.js +355 -8
- package/src/host/cpp/keyslotClient.hpp +231 -0
- package/src/host/cpp/secretsClient.hpp +583 -0
- package/src/host/hostcallWire.js +183 -0
- package/src/host/index.js +2 -0
- package/src/host/isomorphicLoader.js +44 -7
- package/src/host/nodeHost.js +227 -8
- package/src/host/sabHostcallChannel.js +206 -0
- package/src/host/timerDriver.js +203 -0
- package/src/host/wasiShim.js +41 -1
- package/src/host/wasiThreadBrowserWorker.mjs +48 -0
- package/src/host/wasiThreadHost.js +393 -0
- package/src/host/wasiThreadWorker.mjs +32 -0
- package/src/host/wasiThreadWorkerRuntime.js +93 -0
- package/src/http/index.js +339 -0
- package/src/index.d.ts +716 -10
- package/src/index.js +4 -0
- package/src/invoke/codec.js +1202 -128
- package/src/invoke/index.js +5 -1
- package/src/licensing/index.d.ts +2 -0
- package/src/licensing/index.js +2 -0
- package/src/licensing/records.js +287 -8
- package/src/manifest/codec.js +62 -14
- package/src/manifest/index.js +2 -0
- package/src/manifest/legacyToPlg.js +164 -25
- package/src/manifest/normalize.js +1 -0
- package/src/manifest/plgCodec.js +1303 -62
- package/src/manifest/typeRefs.js +162 -24
- package/src/runtime/compiledRuntimeAbi.js +47 -0
- package/src/runtime/compiledRuntimeAbi.json +33 -0
- package/src/runtime/index.d.ts +32 -0
- package/src/runtime/index.js +1 -0
- package/src/runtime-host/index.js +3 -0
- package/src/runtime-host/methodRegistry.js +55 -0
- package/src/standards/index.js +200 -56
- package/src/standards/sharedCatalog.js +16 -0
- package/src/testing/browserModuleHarness.js +604 -31
- package/src/testing/docker/wasmedge-parity.Dockerfile +39 -0
- package/src/testing/index.d.ts +151 -0
- package/src/testing/index.js +21 -0
- package/src/testing/native/wasmedge_emscripten_pthread_runner.c +25 -1
- package/src/testing/parityBrowserRunner.js +138 -0
- package/src/testing/parityHarness.js +616 -0
- package/src/testing/parityLanes.js +537 -0
- package/src/testing/processInvoke.js +29 -21
- package/src/testing/streamInvokeCodec.js +10 -175
- package/src/testing/wasmedgePin.json +6 -0
- package/src/testing/workerModuleHarness.js +242 -0
- package/src/testing/workerModuleHarnessWorker.js +176 -0
- package/src/transport/index.js +3 -0
- package/src/transport/pki.js +299 -11
- package/src/transport/records.js +16 -7
- package/src/utils/ecdsaDer.js +106 -0
- package/src/utils/wasmCrypto.js +0 -43
- package/templates/gpu-module/README.md +48 -0
- package/templates/gpu-module/include/space_data_gpu_abi.h +122 -0
- package/templates/gpu-module/manifest.json +84 -0
- package/schemas/PluginInvokeRequest.fbs +0 -18
- package/schemas/PluginInvokeResponse.fbs +0 -30
- package/schemas/spacedatastandards/PLG.fbs +0 -191
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts +0 -51
- package/src/generated/orbpro/invoke/plugin-invoke-request.d.ts.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-request.js +0 -131
- package/src/generated/orbpro/invoke/plugin-invoke-request.js.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-request.ts +0 -173
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts +0 -76
- package/src/generated/orbpro/invoke/plugin-invoke-response.d.ts.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-response.js +0 -184
- package/src/generated/orbpro/invoke/plugin-invoke-response.js.map +0 -1
- package/src/generated/orbpro/invoke/plugin-invoke-response.ts +0 -243
- package/src/generated/orbpro/invoke.d.ts +0 -3
- package/src/generated/orbpro/invoke.js +0 -5
- package/src/generated/spacedatastandards/plg/entry-function.js +0 -86
- package/src/generated/spacedatastandards/plg/entry-function.ts +0 -119
- package/src/generated/spacedatastandards/plg/index.js +0 -16
- package/src/generated/spacedatastandards/plg/index.ts +0 -11
- package/src/generated/spacedatastandards/plg/plg.js +0 -657
- package/src/generated/spacedatastandards/plg/plg.ts +0 -924
- package/src/generated/spacedatastandards/plg/plugin-capability.js +0 -66
- package/src/generated/spacedatastandards/plg/plugin-category.js +0 -15
- package/src/generated/spacedatastandards/plg/plugin-category.ts +0 -53
- package/src/generated/spacedatastandards/plg/plugin-dependency.js +0 -63
- package/src/generated/spacedatastandards/plg/plugin-dependency.ts +0 -86
- package/src/generated/spacedatastandards/plg/publication-state.js +0 -9
- package/src/generated/spacedatastandards/plg/purchase-tier.js +0 -9
- /package/src/generated/spacedatastandards/plg/{publication-state.ts → publicationState.ts} +0 -0
- /package/src/generated/spacedatastandards/plg/{purchase-tier.ts → purchaseTier.ts} +0 -0
package/src/transport/pki.js
CHANGED
|
@@ -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,130 @@ async function deriveAesKey(sharedSecret, salt, context) {
|
|
|
53
80
|
);
|
|
54
81
|
}
|
|
55
82
|
|
|
83
|
+
function normalizeOptionalBytes(value) {
|
|
84
|
+
if (value === null || value === undefined) {
|
|
85
|
+
return new Uint8Array(0);
|
|
86
|
+
}
|
|
87
|
+
if (typeof value === "string") {
|
|
88
|
+
return hexToBytes(value);
|
|
89
|
+
}
|
|
90
|
+
return toUint8Array(value);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function normalizeRequiredString(value, name) {
|
|
94
|
+
const normalized = String(value ?? "").trim();
|
|
95
|
+
if (!normalized) {
|
|
96
|
+
throw new Error(`${name} is required.`);
|
|
97
|
+
}
|
|
98
|
+
return normalized;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function normalizeArtifactBinding(artifact = {}) {
|
|
102
|
+
const listingId = normalizeRequiredString(artifact.listingId, "artifact.listingId");
|
|
103
|
+
const moduleId = normalizeRequiredString(artifact.moduleId, "artifact.moduleId");
|
|
104
|
+
const version = normalizeRequiredString(artifact.version, "artifact.version");
|
|
105
|
+
const encryptedCid = normalizeRequiredString(
|
|
106
|
+
artifact.encryptedCid,
|
|
107
|
+
"artifact.encryptedCid",
|
|
108
|
+
);
|
|
109
|
+
const providerId = normalizeRequiredString(artifact.providerId, "artifact.providerId");
|
|
110
|
+
const policyId = normalizeRequiredString(artifact.policyId, "artifact.policyId");
|
|
111
|
+
const keyEpoch = normalizeRequiredString(artifact.keyEpoch, "artifact.keyEpoch");
|
|
112
|
+
const contentKeyId =
|
|
113
|
+
String(artifact.contentKeyId ?? "").trim() ||
|
|
114
|
+
`${listingId}:${moduleId}:${version}:${keyEpoch}`;
|
|
115
|
+
const encryptedHash = normalizeOptionalBytes(artifact.encryptedHash);
|
|
116
|
+
if (encryptedHash.length !== 32) {
|
|
117
|
+
throw new Error("artifact.encryptedHash must be 32 bytes.");
|
|
118
|
+
}
|
|
119
|
+
const manifestHash = normalizeOptionalBytes(artifact.manifestHash);
|
|
120
|
+
if (manifestHash.length !== 32) {
|
|
121
|
+
throw new Error("artifact.manifestHash must be 32 bytes.");
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
listingId,
|
|
125
|
+
moduleId,
|
|
126
|
+
version,
|
|
127
|
+
encryptedCid,
|
|
128
|
+
encryptedHash: bytesToHex(encryptedHash),
|
|
129
|
+
providerId,
|
|
130
|
+
policyId,
|
|
131
|
+
keyEpoch,
|
|
132
|
+
manifestHash: bytesToHex(manifestHash),
|
|
133
|
+
contentKeyId,
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export function createMarketplaceContentAad(artifact = {}) {
|
|
138
|
+
const binding = normalizeArtifactBinding(artifact);
|
|
139
|
+
return canonicalBytes({
|
|
140
|
+
encryptedCid: binding.encryptedCid,
|
|
141
|
+
encryptedHash: binding.encryptedHash,
|
|
142
|
+
keyEpoch: binding.keyEpoch,
|
|
143
|
+
listingId: binding.listingId,
|
|
144
|
+
manifestHash: binding.manifestHash,
|
|
145
|
+
moduleId: binding.moduleId,
|
|
146
|
+
policyId: binding.policyId,
|
|
147
|
+
providerId: binding.providerId,
|
|
148
|
+
version: binding.version,
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function createWrapAad({ artifact, recipient, algorithm }) {
|
|
153
|
+
return canonicalBytes({
|
|
154
|
+
algorithm,
|
|
155
|
+
contentKeyId: artifact.contentKeyId,
|
|
156
|
+
encryptedCid: artifact.encryptedCid,
|
|
157
|
+
expiresAtMs: Number(recipient.expiresAtMs ?? 0),
|
|
158
|
+
grantId: normalizeRequiredString(recipient.grantId, "recipient.grantId"),
|
|
159
|
+
keyEpoch: artifact.keyEpoch,
|
|
160
|
+
providerId: artifact.providerId,
|
|
161
|
+
recipientKeyId: normalizeRequiredString(
|
|
162
|
+
recipient.recipientKeyId,
|
|
163
|
+
"recipient.recipientKeyId",
|
|
164
|
+
),
|
|
165
|
+
scope: normalizeRequiredString(recipient.scope, "recipient.scope"),
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function encodeContentKeyMaterial({ keyId, keyBytes, expiresAtMs }) {
|
|
170
|
+
const builder = new flatbuffers.Builder(256);
|
|
171
|
+
const keyIdOffset = builder.createString(keyId);
|
|
172
|
+
const keyBytesOffset = KMF.createKeyBytesVector(builder, keyBytes);
|
|
173
|
+
const root = KMF.createKMF(
|
|
174
|
+
builder,
|
|
175
|
+
keyIdOffset,
|
|
176
|
+
keyMaterialRole.PublicationContent,
|
|
177
|
+
keyMaterialAlgorithm.Aes256Gcm,
|
|
178
|
+
keyMaterialEncoding.RawBytes,
|
|
179
|
+
keyBytesOffset,
|
|
180
|
+
1,
|
|
181
|
+
BigInt(Number(expiresAtMs ?? 0)),
|
|
182
|
+
);
|
|
183
|
+
KMF.finishKMFBuffer(builder, root);
|
|
184
|
+
return builder.asUint8Array();
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
function decodeContentKeyMaterial(bytes) {
|
|
188
|
+
const payload = toUint8Array(bytes);
|
|
189
|
+
const bb = new flatbuffers.ByteBuffer(payload);
|
|
190
|
+
if (!KMF.bufferHasIdentifier(bb)) {
|
|
191
|
+
throw new Error("Wrapped marketplace content key payload is not a KMF record.");
|
|
192
|
+
}
|
|
193
|
+
const kmf = KMF.getRootAsKMF(bb);
|
|
194
|
+
if (kmf.ROLE() !== keyMaterialRole.PublicationContent) {
|
|
195
|
+
throw new Error("Wrapped marketplace key material is not a publication content key.");
|
|
196
|
+
}
|
|
197
|
+
if (kmf.ALGORITHM() !== keyMaterialAlgorithm.Aes256Gcm) {
|
|
198
|
+
throw new Error("Wrapped marketplace key material is not an AES-256-GCM key.");
|
|
199
|
+
}
|
|
200
|
+
const keyBytes = kmf.keyBytesArray();
|
|
201
|
+
if (!keyBytes || keyBytes.length !== 32) {
|
|
202
|
+
throw new Error("Wrapped marketplace content key must be 32 bytes.");
|
|
203
|
+
}
|
|
204
|
+
return new Uint8Array(keyBytes);
|
|
205
|
+
}
|
|
206
|
+
|
|
56
207
|
export async function generateX25519Keypair() {
|
|
57
208
|
const privateKey = await randomBytes(32);
|
|
58
209
|
const publicKey = await x25519PublicKey(privateKey);
|
|
@@ -62,6 +213,121 @@ export async function generateX25519Keypair() {
|
|
|
62
213
|
};
|
|
63
214
|
}
|
|
64
215
|
|
|
216
|
+
export async function protectMarketplaceContent({
|
|
217
|
+
plaintext,
|
|
218
|
+
artifact,
|
|
219
|
+
recipients = [],
|
|
220
|
+
contentKey = null,
|
|
221
|
+
contentNonce = null,
|
|
222
|
+
providerWrapKeyPair = null,
|
|
223
|
+
wrapNonce = null,
|
|
224
|
+
} = {}) {
|
|
225
|
+
if (!Array.isArray(recipients) || recipients.length === 0) {
|
|
226
|
+
throw new Error("protectMarketplaceContent requires at least one recipient.");
|
|
227
|
+
}
|
|
228
|
+
const binding = normalizeArtifactBinding(artifact);
|
|
229
|
+
const keyBytes = contentKey ? toUint8Array(contentKey) : await randomBytes(32);
|
|
230
|
+
if (keyBytes.length !== 32) {
|
|
231
|
+
throw new Error("Marketplace content keys must be 32 bytes.");
|
|
232
|
+
}
|
|
233
|
+
const nonce = contentNonce ? toUint8Array(contentNonce) : await randomBytes(12);
|
|
234
|
+
if (nonce.length !== 12) {
|
|
235
|
+
throw new Error("AES-256-GCM content encryption requires a 12-byte nonce.");
|
|
236
|
+
}
|
|
237
|
+
const aad = createMarketplaceContentAad(binding);
|
|
238
|
+
const encrypted = await aesGcmEncrypt(
|
|
239
|
+
keyBytes,
|
|
240
|
+
toUint8Array(plaintext),
|
|
241
|
+
nonce,
|
|
242
|
+
aad,
|
|
243
|
+
);
|
|
244
|
+
const wrappedKeys = [];
|
|
245
|
+
for (const recipient of recipients) {
|
|
246
|
+
const sender = providerWrapKeyPair ?? (await generateX25519Keypair());
|
|
247
|
+
const recipientPublicKey = normalizePublicKey(recipient.publicKey);
|
|
248
|
+
const wrapIv = wrapNonce ? toUint8Array(wrapNonce) : await randomBytes(12);
|
|
249
|
+
if (wrapIv.length !== 12) {
|
|
250
|
+
throw new Error("AES-256-GCM key wrapping requires a 12-byte nonce.");
|
|
251
|
+
}
|
|
252
|
+
const wrapAad = createWrapAad({
|
|
253
|
+
artifact: binding,
|
|
254
|
+
recipient,
|
|
255
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM-KMF",
|
|
256
|
+
});
|
|
257
|
+
const sharedSecret = await deriveSharedSecret(
|
|
258
|
+
sender.privateKey,
|
|
259
|
+
recipientPublicKey,
|
|
260
|
+
);
|
|
261
|
+
const wrapContext = `marketplace-content-key:${binding.providerId}:${binding.contentKeyId}:${recipient.recipientKeyId}`;
|
|
262
|
+
const wrapKey = await deriveAesKey(sharedSecret, new Uint8Array(0), wrapContext);
|
|
263
|
+
const keyMaterial = encodeContentKeyMaterial({
|
|
264
|
+
keyId: binding.contentKeyId,
|
|
265
|
+
keyBytes,
|
|
266
|
+
expiresAtMs: recipient.expiresAtMs,
|
|
267
|
+
});
|
|
268
|
+
const wrapped = await aesGcmEncrypt(wrapKey, keyMaterial, wrapIv, wrapAad);
|
|
269
|
+
wrappedKeys.push({
|
|
270
|
+
algorithm: "X25519-HKDF-SHA256-AES-256-GCM-KMF",
|
|
271
|
+
contentKeyId: binding.contentKeyId,
|
|
272
|
+
recipientPeerId: normalizeRequiredString(
|
|
273
|
+
recipient.recipientPeerId,
|
|
274
|
+
"recipient.recipientPeerId",
|
|
275
|
+
),
|
|
276
|
+
recipientKeyId: normalizeRequiredString(
|
|
277
|
+
recipient.recipientKeyId,
|
|
278
|
+
"recipient.recipientKeyId",
|
|
279
|
+
),
|
|
280
|
+
providerId: binding.providerId,
|
|
281
|
+
encryptedCid: binding.encryptedCid,
|
|
282
|
+
grantId: normalizeRequiredString(recipient.grantId, "recipient.grantId"),
|
|
283
|
+
scope: normalizeRequiredString(recipient.scope, "recipient.scope"),
|
|
284
|
+
expiresAtMs: Number(recipient.expiresAtMs ?? 0),
|
|
285
|
+
providerEphemeralPublicKey: sender.publicKey,
|
|
286
|
+
nonce: wrapIv,
|
|
287
|
+
aad: wrapAad,
|
|
288
|
+
ciphertext: wrapped.ciphertext,
|
|
289
|
+
tag: wrapped.tag,
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
algorithm: "AES-256-GCM",
|
|
294
|
+
contentKeyId: binding.contentKeyId,
|
|
295
|
+
artifact: binding,
|
|
296
|
+
aad,
|
|
297
|
+
encryptedPayload: {
|
|
298
|
+
algorithm: "AES-256-GCM",
|
|
299
|
+
nonce,
|
|
300
|
+
aad,
|
|
301
|
+
ciphertext: encrypted.ciphertext,
|
|
302
|
+
tag: encrypted.tag,
|
|
303
|
+
},
|
|
304
|
+
wrappedKeys,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export async function decryptMarketplaceContentKeyWrap({
|
|
309
|
+
wrap,
|
|
310
|
+
recipientPrivateKey,
|
|
311
|
+
} = {}) {
|
|
312
|
+
if (!wrap) {
|
|
313
|
+
throw new Error("decryptMarketplaceContentKeyWrap requires wrap.");
|
|
314
|
+
}
|
|
315
|
+
const sharedSecret = await deriveSharedSecret(
|
|
316
|
+
recipientPrivateKey,
|
|
317
|
+
wrap.providerEphemeralPublicKey,
|
|
318
|
+
);
|
|
319
|
+
const wrapContext = `marketplace-content-key:${wrap.providerId}:${wrap.contentKeyId}:${wrap.recipientKeyId}`;
|
|
320
|
+
const wrapKey = await deriveAesKey(sharedSecret, new Uint8Array(0), wrapContext);
|
|
321
|
+
const keyMaterial = await aesGcmDecrypt(
|
|
322
|
+
wrapKey,
|
|
323
|
+
wrap.ciphertext,
|
|
324
|
+
wrap.tag,
|
|
325
|
+
wrap.nonce,
|
|
326
|
+
wrap.aad,
|
|
327
|
+
);
|
|
328
|
+
return decodeContentKeyMaterial(keyMaterial);
|
|
329
|
+
}
|
|
330
|
+
|
|
65
331
|
async function encryptBytesLegacy({
|
|
66
332
|
plaintext,
|
|
67
333
|
recipientPublicKey,
|
|
@@ -103,6 +369,7 @@ export async function decryptProtectedBytes({
|
|
|
103
369
|
if (!parsed?.enc) {
|
|
104
370
|
return toUint8Array(protectedBytes);
|
|
105
371
|
}
|
|
372
|
+
assertGcmEncRecord(parsed.enc);
|
|
106
373
|
const sharedSecret = await deriveSharedSecret(
|
|
107
374
|
recipientPrivateKey,
|
|
108
375
|
parsed.enc.ephemeralPublicKey,
|
|
@@ -112,7 +379,14 @@ export async function decryptProtectedBytes({
|
|
|
112
379
|
new Uint8Array(0),
|
|
113
380
|
parsed.enc.context ?? "",
|
|
114
381
|
);
|
|
115
|
-
|
|
382
|
+
const { ciphertext, tag } = splitGcmPayload(parsed.payloadBytes);
|
|
383
|
+
return aesGcmDecrypt(
|
|
384
|
+
aesKey,
|
|
385
|
+
ciphertext,
|
|
386
|
+
tag,
|
|
387
|
+
parsed.enc.nonceStart,
|
|
388
|
+
encodeEncRecord(parsed.enc),
|
|
389
|
+
);
|
|
116
390
|
}
|
|
117
391
|
|
|
118
392
|
export async function encryptBytesForRecipient({
|
|
@@ -134,11 +408,10 @@ export async function encryptBytesForRecipient({
|
|
|
134
408
|
recipientPublicKey,
|
|
135
409
|
);
|
|
136
410
|
const aesKey = await deriveAesKey(sharedSecret, new Uint8Array(0), context);
|
|
137
|
-
const ciphertext = await aesCtrEncrypt(aesKey, toUint8Array(plaintext), nonceStart);
|
|
138
411
|
const enc = {
|
|
139
412
|
version: 1,
|
|
140
413
|
keyExchange: "X25519",
|
|
141
|
-
symmetric: "
|
|
414
|
+
symmetric: "AES_256_GCM",
|
|
142
415
|
keyDerivation: "HKDF_SHA256",
|
|
143
416
|
ephemeralPublicKey: sender.publicKey,
|
|
144
417
|
nonceStart,
|
|
@@ -148,15 +421,29 @@ export async function encryptBytesForRecipient({
|
|
|
148
421
|
rootType,
|
|
149
422
|
timestamp: Date.now(),
|
|
150
423
|
};
|
|
424
|
+
// The encoded ENC record doubles as the GCM AAD so every delivery parameter
|
|
425
|
+
// (context, schema hash, root type, recipient key id, nonce, ephemeral key)
|
|
426
|
+
// is authenticated alongside the ciphertext. encodeEncRecord() is
|
|
427
|
+
// deterministic for a normalized record, so decrypt paths recompute the
|
|
428
|
+
// identical bytes from the parsed ENC record.
|
|
429
|
+
const { ciphertext, tag } = await aesGcmEncrypt(
|
|
430
|
+
aesKey,
|
|
431
|
+
toUint8Array(plaintext),
|
|
432
|
+
nonceStart,
|
|
433
|
+
encodeEncRecord(enc),
|
|
434
|
+
);
|
|
435
|
+
const payloadBytes = new Uint8Array(ciphertext.length + tag.length);
|
|
436
|
+
payloadBytes.set(ciphertext, 0);
|
|
437
|
+
payloadBytes.set(tag, ciphertext.length);
|
|
151
438
|
const recordCollectionBytes = encodePublicationRecordCollection({ enc });
|
|
152
439
|
const protectedBlobBytes = appendPublicationRecordCollection(
|
|
153
|
-
|
|
440
|
+
payloadBytes,
|
|
154
441
|
recordCollectionBytes,
|
|
155
442
|
);
|
|
156
443
|
return createEncryptedEnvelopePayload({
|
|
157
444
|
protectedBlobBytes,
|
|
158
445
|
parsedProtectedBlob: {
|
|
159
|
-
payloadBytes
|
|
446
|
+
payloadBytes,
|
|
160
447
|
recordCollectionBytes,
|
|
161
448
|
enc,
|
|
162
449
|
pnm: null,
|
|
@@ -182,7 +469,9 @@ export async function decryptBytesFromEnvelope({
|
|
|
182
469
|
});
|
|
183
470
|
}
|
|
184
471
|
if (envelope.ciphertextBase64 && envelope.encRecordBase64) {
|
|
185
|
-
const
|
|
472
|
+
const encRecordBytes = base64ToBytes(envelope.encRecordBase64);
|
|
473
|
+
const enc = decodeEncRecord(encRecordBytes);
|
|
474
|
+
assertGcmEncRecord(enc);
|
|
186
475
|
const sharedSecret = await deriveSharedSecret(
|
|
187
476
|
recipientPrivateKey,
|
|
188
477
|
enc.ephemeralPublicKey,
|
|
@@ -192,11 +481,10 @@ export async function decryptBytesFromEnvelope({
|
|
|
192
481
|
new Uint8Array(0),
|
|
193
482
|
enc.context ?? envelope.context ?? "",
|
|
194
483
|
);
|
|
195
|
-
|
|
196
|
-
aesKey,
|
|
484
|
+
const { ciphertext, tag } = splitGcmPayload(
|
|
197
485
|
base64ToBytes(envelope.ciphertextBase64),
|
|
198
|
-
enc.nonceStart,
|
|
199
486
|
);
|
|
487
|
+
return aesGcmDecrypt(aesKey, ciphertext, tag, enc.nonceStart, encRecordBytes);
|
|
200
488
|
}
|
|
201
489
|
const sharedSecret = await deriveSharedSecret(
|
|
202
490
|
recipientPrivateKey,
|
package/src/transport/records.js
CHANGED
|
@@ -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
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
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-
|
|
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
|
+
}
|
package/src/utils/wasmCrypto.js
CHANGED
|
@@ -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.
|