aere-quantum/proof-of-ai/proof-of-ai.mjs
Aere Network cf8c56792f ai-trust, proof-of-ai, verifiable-data: the trust chain of an AI result, the AIP-23 envelope of an agent action, and a dataset whose answers are checkable without the data
ai-trust/ links six existing proofs (agent identity, model artifact attestation, host runtime record, policy and signed ledger,
Proof of AI envelope, on-chain witness) into one bundle judged by one verifier that checks only the links; 13/13 in the lab,
16/16 live on testnet 28001 (ledger head notarized). proof-of-ai/ is the AIP-23 envelope builder it uses. verifiable-data/
publishes append-only versions with an RFC 9162 root and a sorted index per field, range and equality queries proven correct
and complete, selective disclosure per field, availability by sampling, and the AIP-23 data envelope notarized (version 2 on
testnet 28001). agents/agent-ancora.mjs gains notarizeEnvelope({kind}), the general form of notarizeHead. Each README says what
is not built: zero-knowledge queries need a prover and are not here. No third party has reviewed any of this.
2026-10-02 11:28:14 +03:00

53 lines
3.2 KiB
JavaScript

'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')) };
}