xoonya 3.1.8 → 3.1.10

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/RELEASE_NOTES.md CHANGED
@@ -1,10 +1,3 @@
1
- `xoonya` 3.1.8 is the synchronized release that keeps the proof line aligned with the runtime.
1
+ `xoonya` 3.1.10 refreshes the public README and package metadata to lead with the proven capabilities: deterministic and post-quantum (Ed25519 + ML-DSA-65 hybrid) verification of the native XNYA machine-evidence format, demonstrated live via the paid x402 lane.
2
2
 
3
- This release carries no change to the proof engine, the native XNYA standard, the verification methods, the conformance vectors, or the public proof surfaces. It exists to keep the proof package on the same synchronized line as the runtime, which in this cycle refreshed the public MCP executor's machine-readable description to lead with its pay-per-call story.
4
-
5
- Highlights:
6
-
7
- - keeps the deterministic hash, sign, and verify core, the verification-class and strict-mode behavior, and the trust-root options unchanged
8
- - keeps the conformance and forgery-resistance vectors and the full verifier suite passing
9
- - keeps the canonical `https://naxytra.com/xoonya` public product URL and the synchronized package posture intact
10
- - tracks the runtime's discovery-description refresh so the proof and runtime packages stay on one release number
3
+ There is no change to the proof engine, verification behavior, vectors, or any route — this is a documentation and packaging refresh for public outreach.
package/START_HERE.md CHANGED
@@ -4,7 +4,7 @@ This is the shortest reliable path for understanding and using the public `xoony
4
4
 
5
5
  The phase program is now complete, so this file is the right starting point for a closed and release-shaped proof system rather than an in-flight milestone build.
6
6
 
7
- The product-side implementation, proof posture, and bounded hybrid verification work for the widened `3.0.0` finish line are now complete. The remaining step is the synchronized public `3.0.0` release cut, publish, deploy, and verification sequence documented in [NAXYTRA_3_0_0_RELEASE_CONTRACT.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/docs/release/NAXYTRA_3_0_0_RELEASE_CONTRACT.md) and [PUBLISH_PLAN.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PUBLISH_PLAN.md).
7
+ The product-side implementation, proof posture, and bounded hybrid verification work for the widened `3.0.0` finish line are now complete. The remaining step is the synchronized public `3.0.0` release cut, publish, deploy, and verification sequence documented in NAXYTRA_3_0_0_RELEASE_CONTRACT.md and PUBLISH_PLAN.md.
8
8
 
9
9
  If you are arriving from the broader public discovery layer, the canonical entry points are:
10
10
 
@@ -68,13 +68,13 @@ This is the fastest way to see the intended proof-side package story end-to-end.
68
68
 
69
69
  If you want the clearest cross-repo adoption path instead of the broad package tour, continue with:
70
70
 
71
- - [CARRIED_HANDOFF_DEMO.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/CARRIED_HANDOFF_DEMO.md)
71
+ - CARRIED_HANDOFF_DEMO.md
72
72
 
73
73
  If you want the shortest neutral external-adoption bundle, continue with:
74
74
 
75
- - [PARTNER_READY_PATH.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PARTNER_READY_PATH.md)
76
- - [PUBLIC_DEMO_SCRIPT.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PUBLIC_DEMO_SCRIPT.md)
77
- - [EXAMPLE_PATHS.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/EXAMPLE_PATHS.md)
75
+ - PARTNER_READY_PATH.md
76
+ - PUBLIC_DEMO_SCRIPT.md
77
+ - EXAMPLE_PATHS.md
78
78
  - `node examples/partner_proof_walkthrough.js`
79
79
 
80
80
  ## 3. Verify The Whole Package
@@ -91,8 +91,8 @@ This is the production-confidence check for the published proof package surface.
91
91
 
92
92
  For long-term product understanding, read:
93
93
 
94
- - [FINAL_CONTRACT.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/FINAL_CONTRACT.md)
95
- - [SERVICE_CONTRACT.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/SERVICE_CONTRACT.md)
94
+ - FINAL_CONTRACT.md
95
+ - SERVICE_CONTRACT.md
96
96
  - `GET /openapi.json`
97
97
  - `GET /asyncapi.json`
98
98
  - `GET /cloudevents.json`
@@ -117,23 +117,23 @@ For long-term product understanding, read:
117
117
  - `GET /v1/result-package-trust`
118
118
  - `GET /v1/event-systems`
119
119
  - `GET /v1/integrations`
120
- - [PROGRAM_STATUS.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PROGRAM_STATUS.md)
121
- - [OPERATOR_START_HERE.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/OPERATOR_START_HERE.md)
122
- - [OPERATIONS_RUNBOOK.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/OPERATIONS_RUNBOOK.md)
123
- - [PROGRAM_COMPLETE_RELEASE.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PROGRAM_COMPLETE_RELEASE.md)
124
- - [WHY_XYTARA_XOONYA.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/WHY_XYTARA_XOONYA.md)
125
- - [CARRIED_HANDOFF_DEMO.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/CARRIED_HANDOFF_DEMO.md)
126
- - [PARTNER_READY_PATH.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PARTNER_READY_PATH.md)
127
- - [TERMINOLOGY.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/TERMINOLOGY.md)
120
+ - PROGRAM_STATUS.md
121
+ - OPERATOR_START_HERE.md
122
+ - OPERATIONS_RUNBOOK.md
123
+ - PROGRAM_COMPLETE_RELEASE.md
124
+ - WHY_XYTARA_XOONYA.md
125
+ - CARRIED_HANDOFF_DEMO.md
126
+ - PARTNER_READY_PATH.md
127
+ - TERMINOLOGY.md
128
128
 
129
129
  ## 5. If You Are Integrating From Outside
130
130
 
131
131
  Continue with:
132
132
 
133
- - [CROSS_RUNTIME_POSTURE.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/CROSS_RUNTIME_POSTURE.md)
134
- - [integrations/PROOF_INTEGRATION_PROCESS.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/integrations/PROOF_INTEGRATION_PROCESS.md)
135
- - [PARTNER_READY_PATH.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PARTNER_READY_PATH.md)
136
- - [COMPATIBILITY_NOTE.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/COMPATIBILITY_NOTE.md)
133
+ - CROSS_RUNTIME_POSTURE.md
134
+ - integrations/PROOF_INTEGRATION_PROCESS.md
135
+ - PARTNER_READY_PATH.md
136
+ - COMPATIBILITY_NOTE.md
137
137
 
138
138
  ## 6. Production Reading Rule
139
139
 
@@ -155,5 +155,5 @@ If you want the shortest CLI-first read of the package after install, use:
155
155
 
156
156
  Use:
157
157
 
158
- - [PROGRAM_STATUS.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/PROGRAM_STATUS.md)
159
- - [OPERATOR_START_HERE.md](C:/Users/Yoga/Desktop/workspace/vscode_workspace_naxytra/naxytra/xoonya/OPERATOR_START_HERE.md)
158
+ - PROGRAM_STATUS.md
159
+ - OPERATOR_START_HERE.md
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+
3
+ // Cryptographic verification of IMPORTED external proofs.
4
+ //
5
+ // xoonya binds external proof material into its own bundles. This module lets it
6
+ // additionally VERIFY the external material's own signature — reporting the
7
+ // cryptographic FACTS it can establish, without over-claiming trust.
8
+ //
9
+ // Honesty model (important): from a single self-contained request, xoonya can
10
+ // only establish that "a signature is valid under key K" (signature_valid) and
11
+ // report K's fingerprint (signing_key_ref). It CANNOT establish that K is the
12
+ // legitimate issuer/attester, nor revocation or DID-resolution status. Trust in K
13
+ // is the consumer's decision. The only way a caller gets a trust-anchored result
14
+ // (expected_key_match=true) is by DECLARING, out of band, the key fingerprint they
15
+ // already trust (expected_key_ref) and having the signer match it. A key supplied
16
+ // in the same request — or a self-asserted key embedded in the proof — is NOT, by
17
+ // itself, treated as trusted.
18
+ //
19
+ // Dependency-free (node crypto). Supports compact JWS (EdDSA, ES256/384/512,
20
+ // ES256K, RS256/384/512, PS256/384/512) and generic detached signatures. Private
21
+ // key material (e.g. a JWK with a `d` component) is refused.
22
+
23
+ const crypto = require("crypto");
24
+
25
+ function b64urlToBuffer(s) {
26
+ const str = String(s || "").replace(/-/g, "+").replace(/_/g, "/");
27
+ const pad = str.length % 4 === 0 ? "" : "=".repeat(4 - (str.length % 4));
28
+ return Buffer.from(str + pad, "base64");
29
+ }
30
+
31
+ // alg -> { hash, kind, keyType?/curve? } ; curve/keyType bind the declared alg to
32
+ // the actual key so the reported alg describes how it was really validated.
33
+ const JWS_ALG = {
34
+ EdDSA: { hash: null, kind: "eddsa", keyType: "ed25519" },
35
+ ES256: { hash: "sha256", kind: "ecdsa", curve: "prime256v1" },
36
+ ES384: { hash: "sha384", kind: "ecdsa", curve: "secp384r1" },
37
+ ES512: { hash: "sha512", kind: "ecdsa", curve: "secp521r1" },
38
+ ES256K: { hash: "sha256", kind: "ecdsa", curve: "secp256k1" },
39
+ RS256: { hash: "sha256", kind: "rsa" },
40
+ RS384: { hash: "sha384", kind: "rsa" },
41
+ RS512: { hash: "sha512", kind: "rsa" },
42
+ PS256: { hash: "sha256", kind: "rsapss" },
43
+ PS384: { hash: "sha384", kind: "rsapss" },
44
+ PS512: { hash: "sha512", kind: "rsapss" }
45
+ };
46
+
47
+ function isPrivateJwk(obj) {
48
+ return Boolean(obj && typeof obj === "object" && !Buffer.isBuffer(obj) && typeof obj.d === "string" && obj.d.length > 0);
49
+ }
50
+
51
+ // Build a PUBLIC KeyObject from PEM / base64 DER SPKI / public JWK. Refuses
52
+ // private key material. Returns null on any problem.
53
+ function toPublicKeyObject(input) {
54
+ if (!input) return null;
55
+ try {
56
+ if (typeof input === "object" && !Buffer.isBuffer(input)) {
57
+ if (isPrivateJwk(input)) return null; // never accept private material
58
+ return crypto.createPublicKey({ key: input, format: "jwk" });
59
+ }
60
+ const s = String(input).trim();
61
+ if (/BEGIN (EC |RSA |DSA |OPENSSH |PGP )?PRIVATE KEY/.test(s)) return null;
62
+ if (s.includes("BEGIN ")) return crypto.createPublicKey({ key: s, format: "pem" });
63
+ return crypto.createPublicKey({ key: Buffer.from(s, "base64"), format: "der", type: "spki" });
64
+ } catch (_) {
65
+ return null;
66
+ }
67
+ }
68
+
69
+ function keyRef(keyObject) {
70
+ try {
71
+ const spki = keyObject.export({ type: "spki", format: "der" });
72
+ const algo = keyObject.asymmetricKeyType || "key";
73
+ return `${algo}-spki-sha256:` + crypto.createHash("sha256").update(spki).digest("hex");
74
+ } catch (_) {
75
+ return null;
76
+ }
77
+ }
78
+
79
+ // The declared alg must be consistent with the actual key type/curve.
80
+ function keyMatchesAlg(keyObject, alg) {
81
+ const spec = JWS_ALG[alg];
82
+ if (!spec || !keyObject) return false;
83
+ const t = keyObject.asymmetricKeyType;
84
+ if (spec.kind === "eddsa") return t === "ed25519";
85
+ if (spec.kind === "ecdsa") {
86
+ if (t !== "ec") return false;
87
+ const details = keyObject.asymmetricKeyDetails || {};
88
+ return details.namedCurve === spec.curve;
89
+ }
90
+ if (spec.kind === "rsa" || spec.kind === "rsapss") return t === "rsa" || t === "rsa-pss";
91
+ return false;
92
+ }
93
+
94
+ function verifyWithAlg(alg, signingInput, signature, keyObject) {
95
+ const spec = JWS_ALG[alg];
96
+ if (!spec || !keyObject) return false;
97
+ if (!keyMatchesAlg(keyObject, alg)) return false; // bind declared alg to the key
98
+ const data = Buffer.isBuffer(signingInput) ? signingInput : Buffer.from(String(signingInput), "utf8");
99
+ try {
100
+ if (spec.kind === "eddsa") return crypto.verify(null, data, keyObject, signature);
101
+ if (spec.kind === "ecdsa") return crypto.verify(spec.hash, data, { key: keyObject, dsaEncoding: "ieee-p1363" }, signature);
102
+ if (spec.kind === "rsa") return crypto.verify(spec.hash, data, keyObject, signature);
103
+ if (spec.kind === "rsapss") {
104
+ return crypto.verify(spec.hash, data, { key: keyObject, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST }, signature);
105
+ }
106
+ } catch (_) {
107
+ return false;
108
+ }
109
+ return false;
110
+ }
111
+
112
+ function trustResult(signatureValid, keyObject, keySource, expectedKeyRef, alg, extra) {
113
+ const kref = keyRef(keyObject);
114
+ const expected = typeof expectedKeyRef === "string" && expectedKeyRef.trim() ? expectedKeyRef.trim() : null;
115
+ const expectedMatch = expected ? kref === expected : null;
116
+ return {
117
+ ok: true,
118
+ signature_valid: signatureValid === true,
119
+ signing_key_ref: kref,
120
+ key_source: keySource,
121
+ expected_key_ref: expected,
122
+ // true only when the caller declared a trusted key fingerprint AND the signer
123
+ // matches it; null when no expectation was declared. Trust in signing_key_ref
124
+ // is otherwise the consumer's decision.
125
+ expected_key_match: expectedMatch,
126
+ trust_anchored: signatureValid === true && expectedMatch === true,
127
+ alg,
128
+ ...(extra || {})
129
+ };
130
+ }
131
+
132
+ // Verify a compact JWS. opts = { trusted_public_key?, expected_key_ref? }.
133
+ function verifyJws(jwsCompact, opts) {
134
+ const o = opts && typeof opts === "object" ? opts : {};
135
+ const parts = String(jwsCompact || "").split(".");
136
+ if (parts.length !== 3) return { ok: false, reason: "jws_malformed" };
137
+ const [protectedB64, payloadB64, signatureB64] = parts;
138
+ let header;
139
+ try {
140
+ header = JSON.parse(b64urlToBuffer(protectedB64).toString("utf8"));
141
+ } catch (_) {
142
+ return { ok: false, reason: "jws_header_invalid" };
143
+ }
144
+ const alg = header && typeof header.alg === "string" ? header.alg : null;
145
+ if (alg === "none") return { ok: false, reason: "jws_alg_none_rejected" };
146
+ if (!alg || !JWS_ALG[alg]) return { ok: false, reason: "jws_alg_unsupported", alg: alg || null };
147
+ // Refuse unknown critical extensions and non-standard signing-input variants.
148
+ if (Array.isArray(header.crit) && header.crit.length > 0) return { ok: false, reason: "jws_crit_unsupported" };
149
+ if (header.b64 === false) return { ok: false, reason: "jws_unencoded_payload_unsupported" };
150
+
151
+ const trustedKey = o.trusted_public_key ? toPublicKeyObject(o.trusted_public_key) : null;
152
+ const embeddedKey = !trustedKey && header.jwk ? toPublicKeyObject(header.jwk) : null;
153
+ const keyObject = trustedKey || embeddedKey;
154
+ if (!keyObject) return { ok: false, reason: "no_public_key" };
155
+
156
+ const valid = verifyWithAlg(alg, `${protectedB64}.${payloadB64}`, b64urlToBuffer(signatureB64), keyObject);
157
+ return trustResult(valid, keyObject, trustedKey ? "caller_supplied" : "embedded_self_asserted", o.expected_key_ref, alg, {
158
+ header,
159
+ payload_b64url: payloadB64
160
+ });
161
+ }
162
+
163
+ // Verify a detached signature over `material`. opts = { material, signature,
164
+ // signature_encoding?, public_key, algorithm, expected_key_ref? }.
165
+ function verifyDetachedSignature(opts) {
166
+ const o = opts && typeof opts === "object" ? opts : {};
167
+ const alg = typeof o.algorithm === "string" ? o.algorithm : null;
168
+ if (!alg || !JWS_ALG[alg]) return { ok: false, reason: "algorithm_unsupported", alg: alg || null };
169
+ const keyObject = toPublicKeyObject(o.public_key);
170
+ if (!keyObject) return { ok: false, reason: "no_public_key" };
171
+ if (o.material === undefined || o.material === null) return { ok: false, reason: "material_required" };
172
+ const material = Buffer.isBuffer(o.material) ? o.material : Buffer.from(String(o.material), "utf8");
173
+ let signature;
174
+ try {
175
+ const enc = o.signature_encoding === "hex" ? "hex" : o.signature_encoding === "base64url" ? null : "base64";
176
+ signature = enc ? Buffer.from(String(o.signature || ""), enc) : b64urlToBuffer(o.signature);
177
+ } catch (_) {
178
+ return { ok: false, reason: "signature_invalid" };
179
+ }
180
+ if (signature.length === 0) return { ok: false, reason: "signature_invalid" };
181
+ const valid = verifyWithAlg(alg, material, signature, keyObject);
182
+ return trustResult(valid, keyObject, "caller_supplied", o.expected_key_ref, alg);
183
+ }
184
+
185
+ function looksLikeCompactJws(s) {
186
+ return typeof s === "string" && /^[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+$/.test(s.trim());
187
+ }
188
+
189
+ module.exports = { verifyJws, verifyDetachedSignature, toPublicKeyObject, isPrivateJwk, looksLikeCompactJws };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "xoonya",
3
- "version": "3.1.8",
4
- "description": "Deterministic proof and review engine for receipts, handoffs, governance, and verification.",
3
+ "version": "3.1.10",
4
+ "description": "Deterministic proof and review engine with post-quantum verification (Ed25519 + ML-DSA-65 hybrid) for receipts, handoffs, governance, and the native XNYA machine-evidence format. Verified live via the paid x402 lane.",
5
5
  "main": "index.js",
6
6
  "bin": {
7
7
  "xoonya": "bin/xoonya.js",
@@ -69,13 +69,23 @@
69
69
  "proof-bundle",
70
70
  "deterministic",
71
71
  "machine",
72
- "evidence"
72
+ "evidence",
73
+ "post-quantum",
74
+ "ml-dsa",
75
+ "slh-dsa",
76
+ "pqc",
77
+ "xnya",
78
+ "ed25519",
79
+ "x402"
73
80
  ],
74
81
  "scripts": {
75
82
  "start": "node server.js",
76
83
  "verify:package": "node scripts/verify_all.js",
77
84
  "verify:conformance": "node scripts/verify_vectors.js",
78
85
  "verify:external-proof-import-gate": "node scripts/verify_external_proof_import_gate.js",
86
+ "verify:external-proof-signature": "node scripts/verify_external_proof_signature.js",
87
+ "verify:paid-execute": "node scripts/verify_paid_execute.js",
88
+ "verify:paywall-flag": "node scripts/verify_paywall_flag.js",
79
89
  "verify:integrations": "node scripts/verify_integrations.js",
80
90
  "verify:tooling": "node scripts/verify_tooling.js",
81
91
  "verify:reference-python": "node scripts/verify_reference_python.js",
@@ -92,7 +102,7 @@
92
102
  "verify:service": "node scripts/verify_service.js",
93
103
  "verify:forgery-resistance": "node scripts/verify_forgery_resistance.js",
94
104
  "verify:release-candidate": "node scripts/verify_release_candidate.js",
95
- "verify:all": "node scripts/verify_all.js && node scripts/verify_external_proof_import_gate.js && node scripts/verify_integrations.js && node scripts/verify_tooling.js && node scripts/verify_vectors.js && node scripts/verify_reference_python.js && node scripts/verify_reference_promotion_gate.js && node scripts/verify_reference_rust_scaffold.js && node scripts/verify_native_hybrid_design_gate.js && node scripts/verify_verification_services.js && node scripts/verify_trust_portability.js && node scripts/verify_control_plane_contracts.js && node scripts/verify_control_plane_routes.js && node scripts/verify_examples.js && node scripts/verify_service.js && node scripts/verify_forgery_resistance.js",
105
+ "verify:all": "node scripts/verify_all.js && node scripts/verify_external_proof_import_gate.js && node scripts/verify_integrations.js && node scripts/verify_tooling.js && node scripts/verify_vectors.js && node scripts/verify_reference_python.js && node scripts/verify_reference_promotion_gate.js && node scripts/verify_reference_rust_scaffold.js && node scripts/verify_native_hybrid_design_gate.js && node scripts/verify_verification_services.js && node scripts/verify_trust_portability.js && node scripts/verify_control_plane_contracts.js && node scripts/verify_control_plane_routes.js && node scripts/verify_examples.js && node scripts/verify_service.js && node scripts/verify_forgery_resistance.js && node scripts/verify_external_proof_signature.js && node scripts/verify_paid_execute.js && node scripts/verify_paywall_flag.js",
96
106
  "prepublishOnly": "npm run verify:release-candidate"
97
107
  }
98
108
  }