xoonya 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CROSS_RUNTIME_POSTURE.md +32 -2
- package/README.md +14 -1
- package/RELEASE_NOTES.md +26 -0
- package/SERVICE_CONTRACT.md +4 -0
- package/XNYA_CONFORMANCE_MARK.md +78 -0
- package/XNYA_REFERENCE_IMPLEMENTATIONS.md +157 -0
- package/XOONYA_NATIVE_PROOF_FORMAT.md +2 -0
- package/XOONYA_NATIVE_STANDARD_GOVERNANCE.md +4 -1
- package/bin/xoonya-release.js +19 -1
- package/bin/xoonya.js +1 -0
- package/lib/release_history.js +26 -0
- package/package.json +13 -4
- package/proof_sdk.js +605 -2
- package/reference/python/README.md +35 -0
- package/reference/python/requirements-optional.txt +1 -0
- package/reference/python/verify_vectors.py +209 -0
- package/reference/python/xnya_reference.py +810 -0
- package/reference/rust/Cargo.toml +11 -0
- package/reference/rust/README.md +28 -0
- package/reference/rust/src/lib.rs +87 -0
- package/scripts/verify_all.js +35 -0
- package/scripts/verify_external_proof_import_gate.js +84 -0
- package/scripts/verify_native_hybrid_design_gate.js +108 -0
- package/scripts/verify_reference_promotion_gate.js +74 -0
- package/scripts/verify_reference_python.js +49 -0
- package/scripts/verify_reference_python_crypto.js +87 -0
- package/scripts/verify_reference_rust_scaffold.js +50 -0
- package/scripts/verify_release_candidate.js +19 -0
- package/scripts/verify_service.js +24 -0
- package/scripts/verify_tooling.js +23 -0
- package/server.js +20 -0
- package/vectors/adversarial-vectors.json +27 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# XNYA Python Candidate Reference
|
|
2
|
+
|
|
3
|
+
This folder contains an independent Python candidate for the XNYA atom, payload profile, and line-rate frame vector floor.
|
|
4
|
+
|
|
5
|
+
It does not import the JavaScript implementation. It is not yet a full `XNYA-compatible` reference implementation because full promotion also requires proof-envelope parity, round-trip generation, and conformance-mark review.
|
|
6
|
+
|
|
7
|
+
Run:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
python reference/python/verify_vectors.py
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Current boundary:
|
|
14
|
+
|
|
15
|
+
- implemented: XNYA atom v1/v2 creation, parsing, verification, deterministic reject codes
|
|
16
|
+
- implemented: XNYP payload profile encoding/parsing
|
|
17
|
+
- implemented: line-rate frame checksum vector
|
|
18
|
+
- implemented: canonical event hash parity
|
|
19
|
+
- implemented: receipt emission for external assertion, native digest, legacy OP_RETURN, and native anchored methods
|
|
20
|
+
- implemented: proof-bundle build/verify parity for non-signed native methods
|
|
21
|
+
- implemented: adversarial reason parity for non-signed proof-bundle checks
|
|
22
|
+
- implemented when optional dependency exists: Ed25519 native signed verification with `cryptography`
|
|
23
|
+
- implemented without optional dependency: deterministic `native_signature_crypto_dependency_missing` gate
|
|
24
|
+
- not claimed: always-on native signed cryptographic verification
|
|
25
|
+
- not claimed: secp256k1 or P-256 Python signature-suite verification
|
|
26
|
+
- not claimed: PQ/hybrid verification
|
|
27
|
+
- not claimed: external issuer, chain, custody, auth, or settlement truth
|
|
28
|
+
|
|
29
|
+
Optional Ed25519 suite check:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
npm run verify:reference-python-crypto
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The crypto-enabled command creates a temporary isolated virtual environment, installs `requirements-optional.txt`, and requires the Ed25519 vector to verify.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
cryptography>=42.0.0
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Verify Python XNYA candidate helpers against the published vector floor."""
|
|
3
|
+
|
|
4
|
+
from __future__ import annotations
|
|
5
|
+
|
|
6
|
+
import json
|
|
7
|
+
import pathlib
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
from xnya_reference import (
|
|
11
|
+
XnyaReferenceError,
|
|
12
|
+
build_proof_bundle,
|
|
13
|
+
canonicalize_event,
|
|
14
|
+
create_atom_v1,
|
|
15
|
+
create_atom_v2,
|
|
16
|
+
emit_receipt,
|
|
17
|
+
encode_payload_profile,
|
|
18
|
+
hash_event,
|
|
19
|
+
line_rate_frame_checksum,
|
|
20
|
+
parse_atom,
|
|
21
|
+
parse_payload_profile,
|
|
22
|
+
verify_proof_bundle,
|
|
23
|
+
verify_atom,
|
|
24
|
+
_ed25519_crypto_available,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
ROOT = pathlib.Path(__file__).resolve().parents[2]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def load_json(relative_path: str) -> dict:
|
|
32
|
+
with (ROOT / relative_path).open("r", encoding="utf-8") as handle:
|
|
33
|
+
return json.load(handle)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def assert_equal(actual, expected, message: str) -> None:
|
|
37
|
+
if actual != expected:
|
|
38
|
+
raise AssertionError(f"{message}: expected {expected!r}, got {actual!r}")
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def verify_atom_vectors() -> tuple[int, int]:
|
|
42
|
+
vectors_doc = load_json("vectors/native-atom-vectors.json")
|
|
43
|
+
identity = vectors_doc["identity_material_hex"]
|
|
44
|
+
payload = vectors_doc["payload_ascii"].encode("ascii")
|
|
45
|
+
positive_count = 0
|
|
46
|
+
adversarial_count = 0
|
|
47
|
+
for vector in vectors_doc["vectors"]:
|
|
48
|
+
actual = (
|
|
49
|
+
create_atom_v1(identity, payload if "with-payload" in vector["id"] else None)
|
|
50
|
+
if vector["atom_version"] == "xoonya-native-atom/v1"
|
|
51
|
+
else create_atom_v2(identity, payload if "with-payload" in vector["id"] else None)
|
|
52
|
+
)
|
|
53
|
+
assert_equal(actual["atom_hex"], vector["atom_hex"], f"{vector['id']} atom hex")
|
|
54
|
+
assert_equal(actual["agent_id"], vector["agent_id"], f"{vector['id']} agent id")
|
|
55
|
+
assert_equal(actual["payload_hash_sha256"], vector["payload_hash_sha256"], f"{vector['id']} payload hash")
|
|
56
|
+
parsed = parse_atom(vector["atom_hex"])
|
|
57
|
+
assert_equal(parsed.byte_length, vector["byte_length"], f"{vector['id']} byte length")
|
|
58
|
+
if "atom_hash_sha256" in vector:
|
|
59
|
+
assert_equal(parsed.atom_hash_sha256, vector["atom_hash_sha256"], f"{vector['id']} atom hash")
|
|
60
|
+
verification = verify_atom(vector["atom_hex"], identity_material_hex=identity)
|
|
61
|
+
assert_equal(verification["valid"], True, f"{vector['id']} verify")
|
|
62
|
+
positive_count += 1
|
|
63
|
+
|
|
64
|
+
for vector in vectors_doc["adversarial"]:
|
|
65
|
+
try:
|
|
66
|
+
result = verify_atom(
|
|
67
|
+
vector["atom_hex"],
|
|
68
|
+
identity_material_hex=vector.get("identity_material_hex"),
|
|
69
|
+
payload=vector.get("payload_ascii", "").encode("ascii") if "payload_ascii" in vector else None,
|
|
70
|
+
)
|
|
71
|
+
if result["valid"]:
|
|
72
|
+
raise AssertionError(f"{vector['id']} unexpectedly passed")
|
|
73
|
+
assert_equal(result["error_code"], vector["expected_error_code"], f"{vector['id']} error code")
|
|
74
|
+
except XnyaReferenceError as error:
|
|
75
|
+
assert_equal(error.code, vector["expected_error_code"], f"{vector['id']} error code")
|
|
76
|
+
adversarial_count += 1
|
|
77
|
+
return positive_count, adversarial_count
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def verify_payload_profile_vectors() -> tuple[int, int]:
|
|
81
|
+
vectors_doc = load_json("vectors/native-payload-profile-vectors.json")
|
|
82
|
+
profile_vector = vectors_doc["profile_vector"]
|
|
83
|
+
encoded = encode_payload_profile(profile_vector["input"])
|
|
84
|
+
expected = profile_vector["expected"]
|
|
85
|
+
assert_equal(encoded["canonical_bytes_hex"], expected["canonical_bytes_hex"], "payload profile canonical bytes")
|
|
86
|
+
assert_equal(encoded["payload_hash_sha256"], expected["payload_hash_sha256"], "payload profile hash")
|
|
87
|
+
assert_equal(encoded["schema_hash_sha256"], expected["schema_hash_sha256"], "payload profile schema hash")
|
|
88
|
+
assert_equal(encoded["field_order"], expected["field_order"], "payload profile field order")
|
|
89
|
+
parsed = parse_payload_profile(expected["canonical_bytes_hex"])
|
|
90
|
+
assert_equal(parsed["payload_hash_sha256"], expected["payload_hash_sha256"], "payload profile parsed hash")
|
|
91
|
+
|
|
92
|
+
frame_vector = vectors_doc["line_rate_frame_vector"]
|
|
93
|
+
checksum = line_rate_frame_checksum(bytes.fromhex(frame_vector["atom_hex"]))
|
|
94
|
+
assert_equal(checksum, frame_vector["checksum_hex"], "line-rate frame checksum")
|
|
95
|
+
assert_equal(frame_vector["atom_hex"] + checksum, frame_vector["frame_hex"], "line-rate frame hex")
|
|
96
|
+
return 1, 1
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def verify_proof_vectors() -> tuple[int, int, int, int]:
|
|
100
|
+
vectors_doc = load_json("vectors/conformance-vectors.json")
|
|
101
|
+
positive_count = 0
|
|
102
|
+
verified_count = 0
|
|
103
|
+
signed_crypto_gated_count = 0
|
|
104
|
+
signed_crypto_verified_count = 0
|
|
105
|
+
signed_dependency_missing_count = 0
|
|
106
|
+
anchored_count = 0
|
|
107
|
+
ed25519_available = _ed25519_crypto_available()
|
|
108
|
+
for vector in vectors_doc["vectors"]:
|
|
109
|
+
event = vector["event"]
|
|
110
|
+
expected = vector["expected"]
|
|
111
|
+
canonical_event = canonicalize_event(event)
|
|
112
|
+
assert_equal(hash_event(canonical_event), expected["event_commitment"], f"{vector['id']} event commitment")
|
|
113
|
+
options = dict(vector.get("receipt_options", {}))
|
|
114
|
+
if expected["receipt"].get("algorithm") == "xoonya-native-signed-v1":
|
|
115
|
+
assert_equal(expected["receipt"]["native_proof"]["method"], "xoonya-native-signed-v1", f"{vector['id']} native signed method")
|
|
116
|
+
assert_equal(expected["receipt"]["native_proof"]["signature_suite"], options.get("signature_suite"), f"{vector['id']} native signed suite")
|
|
117
|
+
bundle = {
|
|
118
|
+
"version": expected["proof_bundle_version"],
|
|
119
|
+
"ceb": canonical_event,
|
|
120
|
+
"receipt": expected["receipt"],
|
|
121
|
+
}
|
|
122
|
+
verification = verify_proof_bundle(bundle)
|
|
123
|
+
if ed25519_available:
|
|
124
|
+
assert_equal(verification["valid"], True, f"{vector['id']} native signed verification")
|
|
125
|
+
assert_equal(verification["verification_state"], "verified_native_signature", f"{vector['id']} native signed state")
|
|
126
|
+
signed_crypto_verified_count += 1
|
|
127
|
+
verified_count += 1
|
|
128
|
+
else:
|
|
129
|
+
assert_equal(verification["valid"], False, f"{vector['id']} native signed dependency gate")
|
|
130
|
+
assert_equal(verification["reason"], "native_signature_crypto_dependency_missing", f"{vector['id']} native signed dependency reason")
|
|
131
|
+
signed_dependency_missing_count += 1
|
|
132
|
+
signed_crypto_gated_count += 1
|
|
133
|
+
positive_count += 1
|
|
134
|
+
continue
|
|
135
|
+
if expected["receipt"].get("algorithm") == "xoonya-native-anchored-v1":
|
|
136
|
+
options["anchors"] = vector["anchors"]
|
|
137
|
+
receipt = emit_receipt(canonical_event, options)
|
|
138
|
+
assert_equal(receipt, expected["receipt"], f"{vector['id']} emitted receipt")
|
|
139
|
+
bundle_input = {"event": event, "receipt_options": options}
|
|
140
|
+
if "anchors" in vector:
|
|
141
|
+
bundle_input["anchors"] = vector["anchors"]
|
|
142
|
+
bundle = build_proof_bundle(bundle_input)
|
|
143
|
+
assert_equal(bundle["version"], expected["proof_bundle_version"], f"{vector['id']} proof bundle version")
|
|
144
|
+
assert_equal(bundle["receipt"], expected["receipt"], f"{vector['id']} proof bundle receipt")
|
|
145
|
+
verification = verify_proof_bundle(bundle)
|
|
146
|
+
assert_equal(verification["valid"], True, f"{vector['id']} proof bundle verification")
|
|
147
|
+
if expected["receipt"].get("algorithm") == "xoonya-native-anchored-v1":
|
|
148
|
+
anchored_count += 1
|
|
149
|
+
verified_count += 1
|
|
150
|
+
positive_count += 1
|
|
151
|
+
|
|
152
|
+
adversarial_doc = load_json("vectors/adversarial-vectors.json")
|
|
153
|
+
adversarial_count = 0
|
|
154
|
+
for vector in adversarial_doc["vectors"]:
|
|
155
|
+
if vector["kind"] == "canonicalize_event_error":
|
|
156
|
+
try:
|
|
157
|
+
canonicalize_event(vector["event"])
|
|
158
|
+
raise AssertionError(f"{vector['id']} unexpectedly passed")
|
|
159
|
+
except ValueError as error:
|
|
160
|
+
assert_equal(str(error), vector["expected_reason"], f"{vector['id']} reason")
|
|
161
|
+
adversarial_count += 1
|
|
162
|
+
continue
|
|
163
|
+
if vector["kind"] != "verify_bundle_reason":
|
|
164
|
+
continue
|
|
165
|
+
result = verify_proof_bundle(vector["bundle"])
|
|
166
|
+
expected_reason = vector["expected_reason"]
|
|
167
|
+
if expected_reason == "native_signature_invalid" and not ed25519_available:
|
|
168
|
+
expected_reason = "native_signature_crypto_dependency_missing"
|
|
169
|
+
assert_equal(result["valid"], False, f"{vector['id']} adversarial should fail")
|
|
170
|
+
assert_equal(result["reason"], expected_reason, f"{vector['id']} adversarial reason")
|
|
171
|
+
adversarial_count += 1
|
|
172
|
+
return positive_count, verified_count, signed_crypto_gated_count, adversarial_count + anchored_count, signed_crypto_verified_count, signed_dependency_missing_count
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def main() -> int:
|
|
176
|
+
atom_positive, atom_adversarial = verify_atom_vectors()
|
|
177
|
+
payload_positive, frame_positive = verify_payload_profile_vectors()
|
|
178
|
+
(
|
|
179
|
+
proof_positive,
|
|
180
|
+
proof_verified,
|
|
181
|
+
signed_crypto_gated,
|
|
182
|
+
proof_adversarial_and_anchor,
|
|
183
|
+
signed_crypto_verified,
|
|
184
|
+
signed_dependency_missing,
|
|
185
|
+
) = verify_proof_vectors()
|
|
186
|
+
summary = {
|
|
187
|
+
"ok": True,
|
|
188
|
+
"product": "xoonya",
|
|
189
|
+
"category": "xnya-python-reference-vector-parity",
|
|
190
|
+
"status": "candidate_atom_payload_and_proof_bundle_vector_parity_passed",
|
|
191
|
+
"atom_vector_count": atom_positive,
|
|
192
|
+
"atom_adversarial_count": atom_adversarial,
|
|
193
|
+
"payload_profile_vector_count": payload_positive,
|
|
194
|
+
"line_rate_frame_vector_count": frame_positive,
|
|
195
|
+
"proof_bundle_vector_count": proof_positive,
|
|
196
|
+
"proof_bundle_verified_vector_count": proof_verified,
|
|
197
|
+
"native_signed_crypto_gated_vector_count": signed_crypto_gated,
|
|
198
|
+
"native_signed_crypto_verified_vector_count": signed_crypto_verified,
|
|
199
|
+
"native_signature_crypto_dependency_missing_count": signed_dependency_missing,
|
|
200
|
+
"verified_signature_suite_count": 1 if signed_crypto_verified else 0,
|
|
201
|
+
"proof_adversarial_and_anchor_check_count": proof_adversarial_and_anchor,
|
|
202
|
+
"boundary": "python_candidate_verifies_ed25519_native_signed_vectors_when_cryptography_dependency_is_available_other_signature_suites_stay_gated"
|
|
203
|
+
}
|
|
204
|
+
print(json.dumps(summary, indent=2, sort_keys=True))
|
|
205
|
+
return 0
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
if __name__ == "__main__":
|
|
209
|
+
sys.exit(main())
|