feat(provenance): FIX-4 — verificador attestation on-chain (cierra V3-C1 + squat)
El verificador attestation queda VIVO: una firma producida por el código REAL de Ergon (arkhe-noesis-core, postcard + mensaje domain-separado) verifica byte-fiel en el pallet Substrate. Cierra el FIX-DEFERRED del roadmap (helper de Ergon ya en árbol) + el replay cross-chain V3-C1. origin-chain-types/attestation_verify.rs (nuevo): - ATTESTATION_DOMAIN_TAG + attestation_signed_message: espejo BYTE-IDÉNTICO del oráculo (DC 076d15cc ASP-3). Mensaje = TAG ‖ genesis_hash(32) ‖ payload. - decode_signing_payload: lector postcard SECUENCIAL total y estricto del SigningPayload de Ergon (sin dep nueva en el runtime wasm frágil). Lectores varint u64/u32 con los bounds exactos de postcard (cierra el LOW de fidelidad flagged: verdict/severity/constraints son u32, máx 5 bytes / 5º ≤ 15). Cotas DoS en strings. NUNCA re-serializa (contrato ASP-3). pallet-origin-provenance: - attest_asset(signing_payload: BoundedVec<u8,512>, signature: [u8;64]): recibe los bytes postcard OPACOS + la firma; decodifica, verifica Ed25519 vía sp_io::crypto::ed25519_verify (host function, no bloatea wasm, precedente FIX-3) sobre el mensaje domain-separado con el genesis_hash de ESTA cadena. La pubkey se decodifica del payload (no param aparte). creator = el validador, anchored_at_block real (cerró los placeholders del scaffold). - Dedup-by-BLAKE3 con rechazo EXPLÍCITO (asset_id = BLAKE3 content hash, dentro del payload firmado → replay del mismo blob reusa el asset_id → AlreadyAttested). Hallazgos de la verificación adversarial (workflow ultracode, 3 lentes) cerrados de RAÍZ: - HIGH asset-id squat / provenance poisoning + MEDIUM tier-forgery: el gate era self-attested (level del payload) → cualquiera con una clave Ed25519 anclaba basura institucional bajo el hash PÚBLICO de un asset legítimo y lo envenenaba de forma inmutable. FIX: registro on-chain AuthorizedValidators (pubkey → nivel OIT) gobernado por Root (register_validator/revoke_validator); la membresía es la VERDAD, no el payload. Mismo patrón que TierProfiles de FIX-6 Stage 2a (legitimidad on-chain, no caller-supplied). Sunset a attestation-driven cuando aterrice el registro OIT de Mathi. - MEDIUM método muerto: removido el ValidationAttestation::signing_payload() SCALE divergente (producía bytes que jamás verificarían — footgun). Decisiones (autoridad Pilar 4): sp_io ed25519_verify (consistente FIX-3, estándar Substrate) · dedup-by-asset_id subsume replay exacto · golden vectors generados desde el oráculo REAL de Ergon (seed [7u8;32], genesis 0xAB) = prueba cross-runtime. PENDIENTE (gap legítimo, no bug): OriginChainAttestationSink (impl del trait ValidationAttestationSink de Ergon) es código cliente off-chain — vive en un crate bridge del monorepo (subxt), NO en el chain repo (dependency direction submódulo→monorepo prohibida). Se cablea con la integración Noesis→chain. Tests: 19 provenance (golden vectors cross-runtime + squat cerrado + revoke + anti-replay cross/intra-chain + tamper + malformed) + 72 types (decoder fuzz- equivalente a postcard + fidelidad u32) + 21 suites workspace verde. cargo +1.88. WASM: build VPS-gated (UnknownOpcode 252 ambiental, ver v0.0.58). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3364994cce
commit
ce18e191d0
7 files changed
+769
-475
No files matched your search
@@ -20,21 +20,26 @@ frame-system = { workspace = true }
|
||||
# Runtime API canonical (v0.0.17 PROV-8 — verify_provenance read-only RPC query)
|
||||
sp-api = { workspace = true }
|
||||
|
||||
# Crypto canonical
|
||||
# Crypto canonical. FIX-4: sp-io host function ed25519_verify (no bloatea wasm,
|
||||
# precedente FIX-3 agent-identity) + blake3 para dedup. ed25519-dalek se mantiene
|
||||
# solo para los fixtures de test (dev-deps) — el runtime usa sp_io.
|
||||
blake3 = { workspace = true }
|
||||
ed25519-dalek = { workspace = true }
|
||||
|
||||
# FIX-4 (V3-C1): verificacion Ed25519 on-chain via host function + genesis read.
|
||||
sp-core = { workspace = true }
|
||||
sp-io = { workspace = true }
|
||||
|
||||
# SCALE codec canonical
|
||||
parity-scale-codec = { workspace = true }
|
||||
scale-info = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
# Mock runtime canonical para integration tests v0.0.18 — PROV-3 E2E flow.
|
||||
# Per pallet Substrate convention: sp-io TestExternalities + sp-runtime
|
||||
# AccountId32 + frame_support construct_runtime macro.
|
||||
# Mock runtime canonical para integration tests — PROV-3 E2E flow + golden
|
||||
# vectors ASP-3. ed25519-dalek solo aqui (fixtures); el runtime usa sp_io.
|
||||
sp-core = { workspace = true, default-features = true }
|
||||
sp-io = { workspace = true, default-features = true }
|
||||
sp-runtime = { workspace = true, default-features = true }
|
||||
ed25519-dalek = { workspace = true, default-features = true }
|
||||
|
||||
[features]
|
||||
default = ["std"]
|
||||
@@ -43,6 +48,8 @@ std = [
|
||||
"frame-support/std",
|
||||
"frame-system/std",
|
||||
"sp-api/std",
|
||||
"sp-core/std",
|
||||
"sp-io/std",
|
||||
"parity-scale-codec/std",
|
||||
"scale-info/std",
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user