zk_protocol/lib.rs
1/// General protocol for ZK attestation between agents
2/// This library provides common types and serialization helpers
3/// that any agent can use without depending on other agents' code.
4
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8/// Request to the attester service to generate a ZK proof
9#[derive(Serialize, Deserialize, Debug, Clone)]
10pub struct AttestRequest {
11 pub program_id: String,
12 /// Input data as raw bytes (bincode-serialized)
13 /// Will be passed to the zkVM program via stdin as a single buffer entry.
14 /// For programs that call io::read() multiple times, use `stdin_items` instead.
15 pub input_bytes: Vec<u8>,
16 /// Multiple stdin buffer entries (each pushed separately).
17 /// When present, each entry maps to one sp1_zkvm::io::read() call.
18 /// Takes precedence over `input_bytes` when non-empty.
19 #[serde(default)]
20 pub stdin_items: Vec<Vec<u8>>,
21 /// Expected output for verification (optional, format defined by agent)
22 pub claimed_output: Option<Value>,
23 /// Whether to verify the proof locally before returning
24 #[serde(default = "default_verify")]
25 pub verify_locally: bool,
26}
27
28fn default_verify() -> bool {
29 true
30}
31
32/// Response from the attester service
33#[derive(Serialize, Deserialize, Debug, Clone)]
34pub struct AttestResponse {
35 /// Hex-encoded Groth16 proof for on-chain verification
36 pub proof: String,
37 /// Public values committed by the zkVM program (hex-encoded)
38 pub public_values: String,
39 /// VK hash for on-chain verifier (bytes32)
40 pub vk_hash: String,
41 /// Output from the zkVM program
42 pub verified_output: Value,
43}
44
45/// Response from POST /register-elf
46#[derive(Serialize, Deserialize, Debug, Clone)]
47pub struct RegisterResponse {
48 /// Content-addressable program ID (e.g. "sha256:<hex>")
49 pub program_id: String,
50 /// Version number (defaults to 1)
51 #[serde(default = "default_version")]
52 pub version: i32,
53 /// ISO-8601 timestamp
54 pub registered_at: String,
55}
56
57fn default_version() -> i32 {
58 1
59}
60
61/// Response from an agent's pricing/booking endpoint
62#[derive(Serialize, Deserialize, Debug, Clone)]
63pub struct AgentResponse {
64 /// Agent-specific response data (price, booking ID, etc.)
65 #[serde(flatten)]
66 pub data: Value,
67 /// Program ID for ZK verification
68 pub program_id: String,
69 /// ELF hash of the zkVM program
70 pub elf_hash: String,
71}
72
73/// Helper to serialize any serde-compatible type to bincode bytes
74pub fn serialize_input<T: Serialize>(input: &T) -> Result<Vec<u8>, bincode::Error> {
75 bincode::serialize(input)
76}
77
78/// Helper to deserialize bincode bytes to any serde-compatible type
79pub fn deserialize_output<T: for<'de> Deserialize<'de>>(bytes: &[u8]) -> Result<T, bincode::Error> {
80 bincode::deserialize(bytes)
81}
82
83/// Convert bincode bytes to JSON array format for HTTP transport
84pub fn bytes_to_json_array(bytes: &[u8]) -> Value {
85 Value::Array(bytes.iter().map(|b| Value::Number((*b).into())).collect())
86}
87
88/// Extract bytes from JSON array format
89pub fn json_array_to_bytes(value: &Value) -> Option<Vec<u8>> {
90 if let Value::Array(arr) = value {
91 Some(arr.iter().filter_map(|v| v.as_u64().map(|n| n as u8)).collect())
92 } else {
93 None
94 }
95}