npm package: @ajna-inc/poe
Description: Proof of Execution (PoE) protocol for Credo-ts - zero-knowledge proofs of program execution
Latest version: 0.0.4

# Credo PoE - Proof of Execution Protocol

[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

This package implements the **Proof of Execution (PoE) 1.0 protocol** for Credo-ts, enabling requesters to ask provers to execute named programs and return zero-knowledge proofs that the program executed correctly on inputs bound to a transaction context — while keeping private inputs confidential.

## Features

- 🔐 **Zero-Knowledge Proofs**: Verify program execution without revealing private inputs
- 🔄 **Generic Protocol**: Support for multiple programs and proof systems
- 🛡️ **Anti-Replay Protection**: Strong binding to `{nonce, context_hash, session_id}`
- 🤝 **Capability Negotiation**: Optional proposal/accept phases for flexibility
- 🔍 **Minimal Disclosure**: Proof-only by default, with optional summaries
- 📋 **Registry-Based Trust**: Local enforcement of verifying keys and program parameters
- 🎯 **DIDComm v2**: Full integration with DIDComm messaging

## Installation

```bash
npm install @credo-ts/poe
# or
yarn add @credo-ts/poe
# or
pnpm add @credo-ts/poe
```

## Quick Start

### 1. Setup Agent with PoE Module

```typescript
import { Agent } from '@credo-ts/core'
import { PoeModule } from '@credo-ts/poe'

const agent = new Agent({
  config: {
    label: 'My Agent',
    walletConfig: {
      id: 'my-wallet',
      key: 'my-secret-key',
    },
  },
  modules: {
    poe: new PoeModule(),
  },
})

await agent.initialize()
```

### 2. Register Programs (Requester Side)

```typescript
const poeApi = agent.modules.poe

// Register a program in the registry
await poeApi.registerProgram({
  program_id: 'vendor.policy.eval.v1',
  version: '1',
  name: 'Policy Evaluator',
  allowed_vk_hashes: ['0xVK_HASH_A', '0xVK_HASH_B'],
  public_schema: 'vendor.policy.eval.v1/public@1',
  supports_interactive: false,
  max_runtime_s: 60,
  max_artifact_mb: 8,
})
```

### 3. Request Proof of Execution (Requester)

```typescript
const poeSession = await poeApi.requestProofOfExecution(connectionId, {
  programs: [
    {
      program_id: 'vendor.policy.eval.v1',
      public_constraints: { params_hash: '0x...' },
      inputs: {
        schema: 'vendor.policy.eval.v1/inputs@1',
        by_value: { ttl_s: 60, policy_ref: 'policy-abc@1' },
      },
      disclosure: 'proof-only',
    },
  ],
  bindingContext: {
    nonce: '0x...', // Generated securely
    context_hash: '0x...', // Hash of transaction context
    session_id: '0x...', // Session identifier
  },
  expiry: '2025-11-11T14:35:00Z',
})
```

### 4. Handle Request and Submit Proof (Prover)

```typescript
// Listen for incoming proof requests
agent.events.on(PoeEventTypes.PoeRequestReceived, async (event) => {
  const { poeRecord } = event.payload

  // Execute the program and generate proof
  const proof = await executeProgram(poeRecord.programId, poeRecord.executionPlan)

  // Submit the proof
  await poeApi.submitProof(poeRecord.id, {
    program_id: poeRecord.programId,
    result: 'pass',
    public: {
      schema: 'vendor.policy.eval.v1/public@1',
      nonce: poeRecord.bindingContext.nonce,
      context_hash: poeRecord.bindingContext.context_hash,
      session_id: poeRecord.bindingContext.session_id,
      outputs_hash: '0x...',
      vk_hash: '0x...',
    },
    zk: {
      scheme: 'groth16',
      circuit_id: 'vendor-policy-eval-v1',
      vk_hash: '0x...',
      proof_b64: 'base64(proof)...',
    },
  })
})
```

### 5. Verify Proof (Requester)

```typescript
// Listen for proof submissions
agent.events.on(PoeEventTypes.PoeSubmitReceived, async (event) => {
  const { poeRecord } = event.payload

  // Verification happens automatically in the handler
  if (poeRecord.verificationResult?.verified) {
    console.log('Proof verified successfully!')
    console.log('Receipt:', poeRecord.verificationResult.receipt)
  } else {
    console.error('Proof verification failed:', poeRecord.verificationResult?.errors)
  }
})
```

## Protocol Flow

```
REQUESTER                               PROVER
    |                                      |
    |--- RequestPoeMessage --------------> |
    |                                      |
    |<-- ProposePoeMessage (optional) ---- | [Negotiation]
    |                                      |
    |--- AcceptPoeMessage (optional) ----> |
    |                                      |
    |                                      | [Execution]
    |<-- SubmitPoeMessage ----------------- |
    |                                      |
    |--- CompleteMessage ----------------> |
    |                                      |
```

## Core Concepts

### Binding Context

Every PoE instance is bound to a unique context to prevent replay attacks:

```typescript
interface BindingContext {
  nonce: string // 32-byte hex (0x...)
  context_hash: string // 32-byte hex (0x...)
  session_id: string // 16-byte hex (0x...)
}
```

### Disclosure Levels

- **`proof-only`**: Only the ZK proof is revealed (default)
- **`proof+summary`**: Proof + high-level execution summary
- **`proof+evidence-ref`**: Proof + encrypted evidence references

### Proof Artifacts

```typescript
interface ProofArtifact {
  program_id: string
  result: 'pass' | 'fail' | 'partial'
  public: PublicOutputs // Binding context + outputs
  zk: ZKProof // Zero-knowledge proof
  summary?: ExecutionSummary // Optional
  evidence_refs?: EvidenceReference[] // Optional
}
```

## Advanced Features

### Interactive Programs with Challenges

```typescript
// Send a challenge for multi-round execution
await poeApi.sendChallenge(poeRecordId, {
  steps: [{ action: 'perform', payload: ['taskA', 'taskB'] }],
  ttl_s: 10,
  sequence: 1,
})
```

### Delegation to Attesters

```typescript
// Allow delegation to trusted attesters
await poeApi.requestProofOfExecution(connectionId, {
  programs: [...],
  bindingContext: {...},
  policy: {
    allowed_attesters: ['did:key:z6Mk...', 'did:web:attester.example'],
  },
})
```

### Custom Policies

```typescript
// Register custom execution policies
await poeApi.registerPolicy({
  id: 'my-custom-policy@1',
  enforcementPhase: 'post-sign',
  enforce: async (agentContext, context) => {
    // Custom policy logic
    return { passed: true }
  },
})
```

## API Reference

### PoeApi

- `requestProofOfExecution(connectionId, options)` - Request proof execution
- `submitProof(poeRecordId, proofArtifact)` - Submit proof
- `sendChallenge(poeRecordId, challengeSpec)` - Send challenge
- `sendComplete(poeRecordId, receipt?)` - Signal completion
- `sendProblemReport(poeRecordId, error)` - Report problem
- `registerProgram(metadata)` - Register program
- `registerProofSystem(system)` - Register proof system
- `registerPolicy(policy)` - Register policy

### Events

- `PoeEventTypes.PoeRequestReceived` - Proof request received
- `PoeEventTypes.PoeProposalReceived` - Proposal received
- `PoeEventTypes.PoeChallengeReceived` - Challenge received
- `PoeEventTypes.PoeSubmitReceived` - Proof submission received
- `PoeEventTypes.PoeCompleted` - Protocol completed
- `PoeEventTypes.PoeProblemReport` - Problem reported
- `PoeEventTypes.PoeStateChanged` - State changed

## Error Codes

Standard error codes as per the PoE spec:

- `program_not_supported` - Program not found in registry
- `inputs_invalid` - Invalid program inputs
- `expired_challenge` - Challenge expired
- `policy_violation` - Policy constraint violated
- `invalid_proof` - Proof verification failed
- `vk_unknown` - Verifying key not allowed
- `params_unknown` - Program parameters not allowed
- `context_mismatch` - Binding context mismatch
- `too_large` - Proof/artifact too large
- `rate_limited` - Rate limit exceeded
- `attester_unavailable` - Attester not available

## Security Considerations

1. **Anti-Replay**: Always use fresh, cryptographically secure nonces
2. **Context Binding**: Bind proofs to specific transaction contexts
3. **Registry Enforcement**: Maintain strict allow-lists for VKs and parameters
4. **Expiry**: Set reasonable expiration times for requests
5. **Policy Validation**: Enforce program-specific policies rigorously
6. **Disclosure**: Use `proof-only` unless additional data is required

## Development Status

🚧 **This package is currently under active development.**

### Completed
- ✅ Core data models and message types
- ✅ State machine and protocol flow
- ✅ Registry architecture
- ✅ Anti-replay mechanisms

### In Progress
- 🔄 Message handlers
- 🔄 Core services (verification, nonce, context binding)
- 🔄 Proof system integration

### Planned
- 📋 Policy enforcement framework
- 📋 HPKE integration for sealed witnesses
- 📋 Multi-round proof support
- 📋 Comprehensive test suite

## Contributing

Contributions are welcome! Please see the [main Credo repository](https://github.com/openwallet-foundation/credo-ts) for contribution guidelines.

## Resources

- [PoE Protocol Specification](../../poe.md)
- [Implementation Plan](../../POE_IMPLEMENTATION_PLAN.md)
- [Credo Documentation](https://credo.js.org)
- [DIDComm v2](https://identity.foundation/didcomm-messaging/spec/)

## License

Apache License 2.0 - see [LICENSE](../../LICENSE) for details.