This repository was archived by the owner on Jul 30, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 5
Tee transaction filtering by viewing key #239
Open
kroist
wants to merge
3
commits into
main
Choose a base branch
from
tee-data-processing
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,11 +7,14 @@ pub const VSOCK_PORT: u32 = 5000; | |
| #[derive(Serialize, Deserialize)] | ||
| pub enum Request { | ||
| Ping, | ||
| CalculateReward { viewing_key_base64: String }, | ||
| } | ||
|
|
||
| #[derive(Serialize, Deserialize)] | ||
| pub enum Response { | ||
| Pong, | ||
| CalculateReward { reward: String }, | ||
| Error { message: String }, | ||
|
Comment on lines
+16
to
+17
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Comment: I was wondering what's better here... this generic |
||
| } | ||
|
|
||
| pub type RewardServer = VsockServer<Request, Response>; | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| use std::borrow::Borrow; | ||
|
|
||
| use alloy_primitives::U256; | ||
| use shielder_circuits::{Fr, PrimeField}; | ||
|
|
||
| use crate::Error; | ||
|
|
||
| /// Convert a U256 value to a field element. | ||
| pub fn u256_to_field<Fr: From<[u64; 4]>>(value: impl Borrow<U256>) -> Fr { | ||
| Fr::from(*value.borrow().as_limbs()) | ||
| } | ||
|
|
||
| /// Convert a field element to a U256 value. | ||
| pub fn field_to_u256<F: PrimeField<Repr = [u8; BYTE_LENGTH]>, const BYTE_LENGTH: usize>( | ||
| value: impl Borrow<F>, | ||
| ) -> U256 { | ||
| U256::from_le_bytes(value.borrow().to_repr()) | ||
| } | ||
|
|
||
| pub fn bytes32_to_field(bytes: &[u8; 32]) -> Result<Fr, Error> { | ||
| Fr::from_bytes(bytes) | ||
| .into_option() | ||
| .ok_or(Error::FieldConversion( | ||
| "Failed to convert to Fr".to_string(), | ||
| )) | ||
| } | ||
|
|
||
| pub fn blob_to_field(blob: &[u8]) -> Result<Fr, Error> { | ||
| if blob.len() != 32 { | ||
| return Err(Error::FieldConversion(format!( | ||
| "Expected 32 bytes, but got {} bytes", | ||
| blob.len() | ||
| ))); | ||
| } | ||
|
|
||
| let bytes: [u8; 32] = blob | ||
| .try_into() | ||
| .map_err(|_| Error::FieldConversion("Failed to convert &[u8] to [u8; 32]".to_string()))?; | ||
|
|
||
| bytes32_to_field(&bytes) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| use alloy_primitives::U256; | ||
| use thiserror::Error; | ||
|
|
||
| pub mod crypto; | ||
| pub mod rewards; | ||
|
|
||
| #[derive(Clone, Debug)] | ||
| pub struct ShielderTransaction { | ||
| pub value: U256, | ||
| pub mac_salt: U256, | ||
| pub mac_commitment: U256, | ||
| } | ||
|
|
||
| #[derive(Clone, Debug)] | ||
|
|
||
| pub struct AppState { | ||
| pub txs: Vec<ShielderTransaction>, | ||
| } | ||
|
|
||
| #[derive(Debug, Error)] | ||
| #[error(transparent)] | ||
| #[non_exhaustive] | ||
| pub enum Error { | ||
| #[error("Error reading AR private key file")] | ||
| ARKeyRead(#[from] std::io::Error), | ||
|
|
||
| #[error("Error converting from a little-endian byte representation to grumpkin::Fr")] | ||
| NotAGrumpkinBaseFieldElement, | ||
|
|
||
| #[error("Event is missing some data")] | ||
| MissingData, | ||
|
|
||
| #[error("Field conversion")] | ||
| FieldConversion(String), | ||
|
|
||
| #[error("Error while deserializing public key")] | ||
| DeserializePubKey, | ||
|
|
||
| #[error("Public key does not satisfy y^2 = x^3 - 17")] | ||
| PubkeyNotOnCurve, | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,39 +1,62 @@ | ||
| use log::info; | ||
| use shielder_rewards_common::protocol::{Request, Response, RewardServer, VSOCK_PORT}; | ||
| use shielder_rewards_tee::{rewards::calculate_reward, AppState}; | ||
| use tokio::spawn; | ||
| use tokio_vsock::{VsockAddr, VsockListener, VsockStream, VMADDR_CID_ANY}; | ||
|
|
||
| #[tokio::main] | ||
| async fn main() { | ||
| env_logger::init(); | ||
|
|
||
| if let Err(e) = run_server().await { | ||
| // TODO: Load app state from a file | ||
|
|
||
| let app_state = AppState { txs: vec![] }; | ||
|
|
||
| if let Err(e) = run_server(&app_state).await { | ||
| eprintln!("VSOCK Server error: {}", e); | ||
| } | ||
| } | ||
|
|
||
| async fn run_server() -> Result<(), Box<dyn std::error::Error>> { | ||
| async fn run_server(app_state: &AppState) -> Result<(), Box<dyn std::error::Error>> { | ||
| let listener = VsockListener::bind(VsockAddr::new(VMADDR_CID_ANY, VSOCK_PORT))?; | ||
|
|
||
| loop { | ||
| let (stream, _) = listener.accept().await?; | ||
| spawn(handle_client(stream)); | ||
| spawn(handle_client(stream, app_state.clone())); | ||
| } | ||
| } | ||
|
|
||
| async fn handle_client(stream: VsockStream) { | ||
| let result = do_handle_client(stream).await; | ||
| async fn handle_client(stream: VsockStream, app_state: AppState) { | ||
| let result = do_handle_client(stream, &app_state).await; | ||
| info!("Client disconnected: {:?}", result); | ||
| } | ||
|
|
||
| async fn do_handle_client(stream: VsockStream) -> Result<(), Box<dyn std::error::Error>> { | ||
| async fn do_handle_client( | ||
| stream: VsockStream, | ||
| app_state: &AppState, | ||
| ) -> Result<(), Box<dyn std::error::Error>> { | ||
| let mut server: RewardServer = stream.into(); | ||
|
|
||
| loop { | ||
| server | ||
| .handle_request(async |command| match command { | ||
| Request::Ping => Response::Pong, | ||
| Request::CalculateReward { viewing_key_base64 } => { | ||
| handle_error(calculate_reward(viewing_key_base64, app_state).await) | ||
| } | ||
| }) | ||
| .await?; | ||
| } | ||
| } | ||
|
|
||
| fn handle_error(result: Result<Response, Box<dyn std::error::Error>>) -> Response { | ||
| match result { | ||
| Ok(response) => response, | ||
| Err(e) => { | ||
| eprintln!("Error handling request: {}", e); | ||
| Response::Error { | ||
| message: "Internal server error".to_string(), | ||
| } | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| use alloy_primitives::U256; | ||
| use base64::prelude::*; | ||
| use shielder_circuits::{poseidon::off_circuit::hash, Fr}; | ||
| use shielder_rewards_common::protocol::Response; | ||
|
|
||
| use crate::{ | ||
| crypto::{blob_to_field, u256_to_field}, | ||
| AppState, | ||
| }; | ||
|
|
||
| pub fn viewing_key_filter(viewing_key: Fr, mac_salt: U256, mac_commitment: U256) -> bool { | ||
| let expected_commitment = hash(&[u256_to_field(mac_salt), viewing_key]); | ||
| u256_to_field::<Fr>(mac_commitment).eq(&expected_commitment) | ||
| } | ||
|
|
||
| pub async fn calculate_reward( | ||
| viewing_key_base64: String, | ||
| app_state: &AppState, | ||
| ) -> Result<Response, Box<dyn std::error::Error>> { | ||
| let viewing_key_bytes = BASE64_STANDARD.decode(&viewing_key_base64)?; | ||
|
|
||
| let viewing_key = blob_to_field(&viewing_key_bytes)?; | ||
|
|
||
| let filtered_txs = app_state | ||
| .txs | ||
| .iter() | ||
| .filter(|tx| viewing_key_filter(viewing_key, tx.mac_salt, tx.mac_commitment)) | ||
| .collect::<Vec<_>>(); | ||
|
|
||
| // Here you would calculate the reward based on the filtered transactions. | ||
| let sum = filtered_txs | ||
| .iter() | ||
| .map(|tx| tx.value) | ||
| .fold(U256::ZERO, |acc, value| acc + value); | ||
|
|
||
| // For now, we just return a sum. | ||
|
|
||
| Ok(Response::CalculateReward { | ||
| reward: sum.to_string(), | ||
| }) | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Question: This will need to be encrypted later, right?