'use strict'; // AERE Proof of AI (roadmap B2 / #38): un plic AERE Proof Protocol (AIP-23) care dovedeste provenienta unei actiuni de agent AI - // ce model, ce versiune, ce prompt, ce unelte, ce iesire, ce agent, cine a cerut - astfel incat un tert sa verifice fara sa aiba // incredere in producator, cu ACELASI verificator ca orice alt proof AERE (tools/aere-proof-protocol/verify.mjs). Nu adauga niciun // cod nou de verificare: asta e chiar teza standardului ("un plic, multe feluri de dovada"). Notarizarea + finalitatea post-cuantica // vin gratis din AIP-23 (statementHash notarizat pe AereNotary, acoperit de o ancora PQ). Numai Node 24, node:crypto. // // Se aliniaza cu contractul de pe lant AereAIProof.sol (modelId, inputHash, outputHash, requesterHash): campurile de mai jos se pot // mapa la o atestare on-chain, dar plicul e PORTABIL (nu cere lantul ca sa existe; il cere doar ca sa capete finalitate). import crypto from 'node:crypto'; export const KIND = 'aere-proof-of-ai'; const sha256 = (b) => '0x' + crypto.createHash('sha256').update(b).digest('hex'); const hexOf = (v) => { if (v == null) return null; if (typeof v === 'string' && /^0x[0-9a-fA-F]{64}$/.test(v)) return v.toLowerCase(); // deja un digest return sha256(Buffer.from(typeof v === 'string' ? v : JSON.stringify(v), 'utf8')); }; /** * Construieste un plic Proof-of-AI (AIP-23). Nu tine niciun continut sensibil: doar digesturi. * @param {object} p * @param {{name:string, version?:string, weightsSha256?:string}} p.model * @param {string} [p.prompt] promptul brut (se stocheaza doar digestul) SAU * @param {string} [p.promptHash] digestul promptului (0x+64) daca nu vrei sa-l dai brut * @param {string} [p.input] intrarea (digest stocat) SAU p.inputHash * @param {string} [p.output] iesirea (digest stocat) SAU p.outputHash * @param {string[]} [p.tools] uneltele pe care agentul avea voie sa le foloseasca / le-a folosit * @param {string} [p.agentId] identitatea agentului (adresa / id) * @param {string} [p.requester] cine a cerut (digest stocat) SAU p.requesterHash * @param {string} p.createdAt RFC3339 * @returns {object} plicul AIP-23 { v, kind, statement, statementHash } */ export function buildProofOfAi(p) { if (!p || !p.model || !p.model.name) throw new Error('proof-of-ai: model.name e obligatoriu'); if (!p.createdAt) throw new Error('proof-of-ai: createdAt e obligatoriu (RFC3339)'); const statement = { v: 1, kind: KIND, model: { name: p.model.name, version: p.model.version || null, weightsSha256: p.model.weightsSha256 || null }, promptHash: p.promptHash ? p.promptHash.toLowerCase() : hexOf(p.prompt), inputHash: p.inputHash ? p.inputHash.toLowerCase() : hexOf(p.input), outputHash: p.outputHash ? p.outputHash.toLowerCase() : hexOf(p.output), tools: Array.isArray(p.tools) ? [...p.tools] : [], agentId: p.agentId || null, requesterHash: p.requesterHash ? p.requesterHash.toLowerCase() : hexOf(p.requester), createdAt: p.createdAt, }; const text = JSON.stringify(statement); // canonic AIP-23: ordinea de inserare, SHA-256 return { v: 1, kind: KIND + '-attestation', statement, statementHash: sha256(Buffer.from(text, 'utf8')) }; }