Skip to main content

sp1_sdk/network/tee/
api.rs

1use crate::{
2    network::{signer::NetworkSigner, utils::sign_raw},
3    SP1Stdin,
4};
5use alloy_primitives::{Address, Signature as AlloySignature};
6use serde::{Deserialize, Serialize};
7
8use k256::ecdsa::Signature;
9
10/// The request payload for the TEE server.
11#[derive(Debug, Serialize, Deserialize)]
12pub struct TEERequest {
13    /// The network request id.
14    pub id: [u8; 32],
15    /// The program to execute.
16    pub program: Vec<u8>,
17    /// The cycle limit for the program.
18    pub cycle_limit: u64,
19    /// The stdin for the program.
20    pub stdin: SP1Stdin,
21    /// The signature of the request id.
22    pub signature: AlloySignature,
23}
24
25impl TEERequest {
26    /// The selector for the TEE verifier.
27    pub(crate) async fn new(
28        signer: &NetworkSigner,
29        id: [u8; 32],
30        program: Vec<u8>,
31        stdin: SP1Stdin,
32        cycle_limit: u64,
33    ) -> Result<Self, anyhow::Error> {
34        let signature = sign_raw(&id, signer).await?;
35
36        Ok(Self { id, program, cycle_limit, stdin, signature })
37    }
38}
39
40/// The response payload from the TEE server.
41#[derive(Clone, Debug, Serialize, Deserialize)]
42pub struct TEEResponse {
43    /// The vkey computed by the TEE server.
44    pub vkey: [u8; 32],
45    /// The public values computed by the TEE server.
46    pub public_values: Vec<u8>,
47    /// The signature over the public values and the vkey.
48    /// Computed as keccak256([`keccack256(version)` || `vkey` || `keccack256(public_values)`]).
49    pub signature: Signature,
50    /// The recovery id computed by the TEE server.
51    pub recovery_id: u8,
52}
53
54impl TEEResponse {
55    /// The bytes to prepend to the encoded proof bytes.
56    #[must_use]
57    pub fn as_prefix_bytes(&self) -> Vec<u8> {
58        let mut bytes = Vec::new();
59
60        // Include the version of the SP1 circuit.
61        let version_bytes = super::SP1_TEE_VERSION.to_le_bytes();
62
63        // The length of the version bytes, panics if the length is greater than 255.
64        let version_bytes_len: u8 = version_bytes.len().try_into().unwrap();
65
66        // Push the selector.
67        bytes.extend_from_slice(&Self::selector());
68        // Push v.
69        bytes.extend_from_slice(&self.recovery_id.to_be_bytes());
70        // Push r and s.
71        bytes.extend_from_slice(&self.signature.to_bytes());
72        // Push the version bytes length.
73        bytes.push(version_bytes_len);
74        // Push the version bytes.
75        bytes.extend_from_slice(&version_bytes);
76
77        bytes
78    }
79
80    /// The selector for the TEE verifier.
81    fn selector() -> [u8; 4] {
82        alloy_primitives::keccak256("SP1TeeVerifier")[0..4].try_into().unwrap()
83    }
84}
85
86/// The response payload from the TEE server for the `get_address` endpoint.
87#[derive(Debug, Serialize, Deserialize)]
88pub struct GetAddressResponse {
89    /// The address of the TEE signer.
90    pub address: Address,
91}
92
93/// The underlying payload for the SSE event sent from the TEE server.
94///
95/// This is an implementation detail, and should not be used directly.
96#[derive(Debug, Serialize, Deserialize)]
97pub enum EventPayload {
98    /// The request was successful.
99    Success(TEEResponse),
100    /// The execution failed.
101    Error(String),
102}