This is an automated email from the ASF dual-hosted git repository.

mssun pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git


The following commit(s) were added to refs/heads/develop by this push:
     new 0d5f478  [types] Remove ser/de for worker structs with polished tests 
(#217)
0d5f478 is described below

commit 0d5f478900c76736a6c99c92c01263932fcf4299
Author: Zhaofeng Chen <[email protected]>
AuthorDate: Tue Feb 4 22:09:54 2020 -0800

    [types] Remove ser/de for worker structs with polished tests (#217)
---
 services/proto/src/teaclave_common.rs              |  51 ++------
 services/proto/src/teaclave_execution_service.rs   |  11 +-
 .../enclave/src/teaclave_execution_service.rs      | 103 ++++++---------
 .../enclave/src/teaclave_worker.rs                 | 121 +++++++----------
 types/Cargo.toml                                   |   1 +
 types/src/crypto.rs                                | 145 ++++++++++++++++-----
 types/src/worker.rs                                | 101 +++++++++++---
 worker/src/function/context.rs                     |   2 +-
 worker/src/function/gbdt_training.rs               |  95 ++++++--------
 worker/src/function/mesapy.rs                      |  29 +----
 10 files changed, 350 insertions(+), 309 deletions(-)

diff --git a/services/proto/src/teaclave_common.rs 
b/services/proto/src/teaclave_common.rs
index 9d140c9..aa62d80 100644
--- a/services/proto/src/teaclave_common.rs
+++ b/services/proto/src/teaclave_common.rs
@@ -1,13 +1,9 @@
 #[cfg(feature = "mesalock_sgx")]
 use std::prelude::v1::*;
 
-use anyhow::{bail, ensure, Error, Result};
-use std::format;
-use teaclave_types::{
-    AesGcm128CryptoInfo, AesGcm256CryptoInfo, TeaclaveFileCryptoInfo, 
TeaclaveFileRootKey128,
-};
-
 use crate::teaclave_common_proto as proto;
+use anyhow::{Error, Result};
+use teaclave_types::TeaclaveFileCryptoInfo;
 
 #[derive(Debug)]
 pub struct UserCredential {
@@ -49,48 +45,17 @@ impl From<UserCredential> for proto::UserCredential {
 impl std::convert::TryFrom<proto::FileCryptoInfo> for TeaclaveFileCryptoInfo {
     type Error = Error;
     fn try_from(proto: proto::FileCryptoInfo) -> Result<Self> {
-        let info = match proto.schema.as_str() {
-            "aes_gcm_128" => {
-                let info = AesGcm128CryptoInfo::new(&proto.key, &proto.iv)?;
-                TeaclaveFileCryptoInfo::AesGcm128(info)
-            }
-            "aes_gcm_256" => {
-                let info = AesGcm256CryptoInfo::new(&proto.key, &proto.iv)?;
-                TeaclaveFileCryptoInfo::AesGcm256(info)
-            }
-            "teaclave_file_root_key_128" => {
-                ensure!(
-                    proto.iv.is_empty(),
-                    "IV is not empty for teaclave_file_root_key_128"
-                );
-                let info = TeaclaveFileRootKey128::new(&proto.key)?;
-                TeaclaveFileCryptoInfo::TeaclaveFileRootKey128(info)
-            }
-            _ => bail!("Invalid crypto schema: {}", proto.schema.as_str()),
-        };
-
-        Ok(info)
+        TeaclaveFileCryptoInfo::new(&proto.schema, &proto.key, &proto.iv)
     }
 }
 
 impl std::convert::From<TeaclaveFileCryptoInfo> for proto::FileCryptoInfo {
     fn from(crypto: TeaclaveFileCryptoInfo) -> Self {
-        match crypto {
-            TeaclaveFileCryptoInfo::AesGcm128(info) => proto::FileCryptoInfo {
-                schema: "aes_gcm_128".to_string(),
-                key: info.key.to_vec(),
-                iv: info.iv.to_vec(),
-            },
-            TeaclaveFileCryptoInfo::AesGcm256(info) => proto::FileCryptoInfo {
-                schema: "aes_gcm_256".to_string(),
-                key: info.key.to_vec(),
-                iv: info.iv.to_vec(),
-            },
-            TeaclaveFileCryptoInfo::TeaclaveFileRootKey128(info) => 
proto::FileCryptoInfo {
-                schema: "teaclave_file_root_key_128".to_string(),
-                key: info.key.to_vec(),
-                iv: Vec::new(),
-            },
+        let (key, iv) = crypto.key_iv();
+        proto::FileCryptoInfo {
+            schema: crypto.schema(),
+            key,
+            iv,
         }
     }
 }
diff --git a/services/proto/src/teaclave_execution_service.rs 
b/services/proto/src/teaclave_execution_service.rs
index 90b2af0..7d1b3f2 100644
--- a/services/proto/src/teaclave_execution_service.rs
+++ b/services/proto/src/teaclave_execution_service.rs
@@ -1,5 +1,3 @@
-use serde::{Deserialize, Serialize};
-#[cfg(feature = "mesalock_sgx")]
 use std::prelude::v1::*;
 
 use anyhow::{anyhow, Error, Result};
@@ -12,13 +10,12 @@ pub use proto::TeaclaveExecutionClient;
 pub use proto::TeaclaveExecutionRequest;
 pub use proto::TeaclaveExecutionResponse;
 
-#[derive(Serialize, Deserialize, Debug)]
+#[derive(Debug)]
 pub struct StagedFunctionExecuteRequest {
-    #[serde(flatten)]
-    invocation: WorkerInvocation,
+    pub invocation: WorkerInvocation,
 }
 
-#[derive(Serialize, Deserialize, Debug)]
+#[derive(Debug)]
 pub struct StagedFunctionExecuteResponse {
     pub summary: std::string::String,
 }
@@ -43,7 +40,7 @@ impl 
std::convert::TryFrom<proto::StagedFunctionExecuteRequest> for StagedFuncti
         let ret = Self {
             invocation: WorkerInvocation {
                 runtime_name: proto.runtime_name,
-                executor_type: proto.executor_type.try_into()?,
+                executor_type: proto.executor_type.as_str().try_into()?,
                 function_name: proto.function_name,
                 function_payload: proto.function_payload,
                 function_args: TeaclaveFunctionArguments {
diff --git a/tests/functional_tests/enclave/src/teaclave_execution_service.rs 
b/tests/functional_tests/enclave/src/teaclave_execution_service.rs
index 6733cb3..b7059c7 100644
--- a/tests/functional_tests/enclave/src/teaclave_execution_service.rs
+++ b/tests/functional_tests/enclave/src/teaclave_execution_service.rs
@@ -1,12 +1,16 @@
-use anyhow;
-use serde_json;
-use std::io::Write;
 use std::prelude::v1::*;
-use std::untrusted::fs;
 
+use std::convert::TryInto;
 use teaclave_proto::teaclave_execution_service::*;
 use teaclave_rpc::endpoint::Endpoint;
-use teaclave_types::AesGcm128CryptoInfo;
+
+use teaclave_types::convert_plaintext_file;
+use teaclave_types::hashmap;
+use teaclave_types::TeaclaveFileCryptoInfo;
+use teaclave_types::TeaclaveFunctionArguments;
+use teaclave_types::TeaclaveWorkerFileInfo;
+use teaclave_types::TeaclaveWorkerFileRegistry;
+use teaclave_types::WorkerInvocation;
 
 pub fn run_tests() -> bool {
     use teaclave_test_utils::*;
@@ -18,66 +22,45 @@ fn setup_client() -> TeaclaveExecutionClient {
     TeaclaveExecutionClient::new(channel).unwrap()
 }
 
-fn enc_input_file(input_crypto: &str, plain_input: &str, enc_input: &str) -> 
anyhow::Result<()> {
-    let crypto_info: AesGcm128CryptoInfo = serde_json::from_str(input_crypto)?;
-    let mut bytes = fs::read_to_string(plain_input)?.into_bytes();
-    crypto_info.encrypt(&mut bytes)?;
-
-    let mut file = fs::File::create(enc_input)?;
-    file.write_all(&bytes)?;
-    Ok(())
-}
-
 fn test_invoke_success() {
-    let request_payload = r#"{
-        "runtime_name": "default",
-        "executor_type": "native",
-        "function_name": "gbdt_training",
-        "function_payload": "",
-        "function_args": {
-            "feature_size": "4",
-            "max_depth": "4",
-            "iterations": "100",
-            "shrinkage": "0.1",
-            "feature_sample_ratio": "1.0",
-            "data_sample_ratio": "1.0",
-            "min_leaf_size": "1",
-            "loss": "LAD",
-            "training_optimization_level": "2"
-        },
-        "input_files": {
-            "training_data": {
-                "path": "test_cases/gbdt_training/train.enc",
-                "crypto_info": {
-                    "aes_gcm128": {
-                        "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
14, 15],
-                        "iv": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-                    }
-                }
-            }
-        },
-        "output_files": {
-            "trained_model": {
-                "path": "test_cases/gbdt_training/model.enc.out",
-                "crypto_info": {
-                    "teaclave_file_root_key128": {
-                        "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
14, 15]
-                    }
-                }
-            }
-        }
-    }"#;
+    let mut client = setup_client();
+
+    let function_args = TeaclaveFunctionArguments::new(&hashmap!(
+        "feature_size"  => "4",
+        "max_depth"     => "4",
+        "iterations"    => "100",
+        "shrinkage"     => "0.1",
+        "feature_sample_ratio" => "1.0",
+        "data_sample_ratio" => "1.0",
+        "min_leaf_size" => "1",
+        "loss"          => "LAD",
+        "training_optimization_level" => "2"
+    ));
 
-    let input_crypto = r#"{
-            "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
-            "iv": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-    }"#;
     let enc_input = "test_cases/gbdt_training/train.enc";
     let plain_input = "test_cases/gbdt_training/train.txt";
+    let enc_output = "test_cases/gbdt_training/model.enc.out";
+
+    let input_info = convert_plaintext_file(plain_input, enc_input).unwrap();
+    let input_files = TeaclaveWorkerFileRegistry::new(hashmap!(
+        "training_data".to_string() => input_info));
+
+    let output_info = TeaclaveWorkerFileInfo::new(enc_output, 
TeaclaveFileCryptoInfo::default());
+    let output_files = TeaclaveWorkerFileRegistry::new(hashmap!(
+        "trained_model".to_string() => output_info));
+
+    let request = StagedFunctionExecuteRequest {
+        invocation: WorkerInvocation {
+            runtime_name: "default".to_string(),
+            executor_type: "native".try_into().unwrap(),
+            function_name: "gbdt_training".to_string(),
+            function_payload: String::new(),
+            function_args,
+            input_files,
+            output_files,
+        },
+    };
 
-    enc_input_file(input_crypto, plain_input, enc_input).unwrap();
-    let request: StagedFunctionExecuteRequest = 
serde_json::from_str(request_payload).unwrap();
-    let mut client = setup_client();
     let response_result = client.invoke_function(request);
     assert!(response_result.is_ok());
 }
diff --git a/tests/integration_tests/enclave/src/teaclave_worker.rs 
b/tests/integration_tests/enclave/src/teaclave_worker.rs
index 7951929..5a967f7 100644
--- a/tests/integration_tests/enclave/src/teaclave_worker.rs
+++ b/tests/integration_tests/enclave/src/teaclave_worker.rs
@@ -1,95 +1,66 @@
-use protected_fs::ProtectedFile;
-use std::io::{Read, Write};
+use std::convert::TryInto;
+use std::io::Read;
 use std::prelude::v1::*;
-use std::untrusted::fs;
 
-use serde_json;
-
-use anyhow;
-use teaclave_types::AesGcm128CryptoInfo;
-use teaclave_types::TeaclaveFileRootKey128;
+use teaclave_types::convert_plaintext_file;
+use teaclave_types::hashmap;
+use teaclave_types::read_all_bytes;
+use teaclave_types::TeaclaveFileCryptoInfo;
+use teaclave_types::TeaclaveFunctionArguments;
+use teaclave_types::TeaclaveWorkerFileInfo;
+use teaclave_types::TeaclaveWorkerFileRegistry;
 use teaclave_types::WorkerInvocation;
-use teaclave_worker::Worker;
 
-fn enc_input_file(input_crypto: &str, plain_input: &str, enc_input: &str) -> 
anyhow::Result<()> {
-    let crypto_info: AesGcm128CryptoInfo = serde_json::from_str(input_crypto)?;
-    let mut bytes = fs::read_to_string(plain_input)?.into_bytes();
-    crypto_info.encrypt(&mut bytes)?;
-
-    let mut file = fs::File::create(enc_input)?;
-    file.write_all(&bytes)?;
-    Ok(())
-}
-
-fn dec_output_file(output_crypto: &str, enc_output: &str) -> 
anyhow::Result<String> {
-    let crypto: TeaclaveFileRootKey128 = serde_json::from_str(output_crypto)?;
-    let mut file = ProtectedFile::open_ex(enc_output, &crypto.key)?;
-    let mut result = String::new();
-    file.read_to_string(&mut result)?;
-    Ok(result)
-}
+use teaclave_worker::Worker;
 
 fn test_start_worker() {
-    let request_payload = r#"{
-        "runtime_name": "default",
-        "executor_type": "native",
-        "function_name": "gbdt_training",
-        "function_payload": "",
-        "function_args": {
-            "feature_size": "4",
-            "max_depth": "4",
-            "iterations": "100",
-            "shrinkage": "0.1",
-            "feature_sample_ratio": "1.0",
-            "data_sample_ratio": "1.0",
-            "min_leaf_size": "1",
-            "loss": "LAD",
-            "training_optimization_level": "2"
-        },
-        "input_files": {
-            "training_data": {
-                "path": "test_cases/gbdt_training/train.enc",
-                "crypto_info": {
-                    "aes_gcm128": {
-                        "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
14, 15],
-                        "iv": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-                    }
-                }
-            }
-        },
-        "output_files": {
-            "trained_model": {
-                "path": "test_cases/gbdt_training/model.enc.out",
-                "crypto_info": {
-                    "teaclave_file_root_key128": {
-                        "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 
14, 15]
-                    }
-                }
-            }
-        }
-    }"#;
+    let function_args = TeaclaveFunctionArguments::new(&hashmap!(
+        "feature_size"  => "4",
+        "max_depth"     => "4",
+        "iterations"    => "100",
+        "shrinkage"     => "0.1",
+        "feature_sample_ratio" => "1.0",
+        "data_sample_ratio" => "1.0",
+        "min_leaf_size" => "1",
+        "loss"          => "LAD",
+        "training_optimization_level" => "2"
+    ));
 
-    let input_crypto = r#"{
-            "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
-            "iv": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-    }"#;
     let enc_input = "test_cases/gbdt_training/train.enc";
     let plain_input = "test_cases/gbdt_training/train.txt";
 
-    let output_crypto = r#"{
-        "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
-    }"#;
     let enc_output = "test_cases/gbdt_training/model.enc.out";
     let expected_output = "test_cases/gbdt_training/expected_model.txt";
 
-    enc_input_file(input_crypto, plain_input, enc_input).unwrap();
-    let request: WorkerInvocation = 
serde_json::from_str(request_payload).unwrap();
+    let input_info = convert_plaintext_file(plain_input, enc_input).unwrap();
+
+    let input_files = TeaclaveWorkerFileRegistry::new(hashmap!(
+        "training_data".to_string() => input_info));
+
+    let output_info = TeaclaveWorkerFileInfo::new(enc_output, 
TeaclaveFileCryptoInfo::default());
+
+    let output_files = TeaclaveWorkerFileRegistry::new(hashmap!(
+        "trained_model".to_string() => output_info.clone()));
+
+    let request = WorkerInvocation {
+        runtime_name: "default".to_string(),
+        executor_type: "native".try_into().unwrap(),
+        function_name: "gbdt_training".to_string(),
+        function_payload: String::new(),
+        function_args,
+        input_files,
+        output_files,
+    };
+
     let worker = Worker::default();
     let summary = worker.invoke_function(request).unwrap();
     assert_eq!(summary, "Trained 120 lines of data.");
 
-    let result = dec_output_file(output_crypto, enc_output).unwrap();
-    let expected = fs::read_to_string(&expected_output).unwrap();
+    let mut f = output_info.get_readable_io().unwrap();
+    let mut result = Vec::new();
+    f.read_to_end(&mut result).unwrap();
+
+    let expected = read_all_bytes(expected_output).unwrap();
     assert_eq!(&result[..], &expected[..]);
 }
 
diff --git a/types/Cargo.toml b/types/Cargo.toml
index b9b60ec..0fb3d53 100644
--- a/types/Cargo.toml
+++ b/types/Cargo.toml
@@ -21,6 +21,7 @@ protected_fs_rs  = { path = "../common/protected_fs_rs", 
default-features = fals
 
 anyhow       = { version = "1.0.26" }
 sgx_types    = { version = "1.1.0" }
+rand         = { version = "0.7.0" }
 hex          = { version = "0.4.0" }
 serde        = { version = "1.0.92", features = ["derive"] }
 toml         = { version = "0.5.3" }
diff --git a/types/src/crypto.rs b/types/src/crypto.rs
index 6399bdb..134163e 100644
--- a/types/src/crypto.rs
+++ b/types/src/crypto.rs
@@ -2,35 +2,36 @@
 use std::prelude::v1::*;
 
 use anyhow;
+use rand::prelude::RngCore;
 use ring;
-use serde::{Deserialize, Serialize};
 use std::format;
 
 const AES_GCM_256_KEY_LENGTH: usize = 32;
 const AES_GCM_256_IV_LENGTH: usize = 12;
 
-#[derive(Default, Debug, Serialize, Deserialize)]
+#[derive(Clone, Debug)]
 pub struct AesGcm256CryptoInfo {
     pub key: [u8; AES_GCM_256_KEY_LENGTH],
     pub iv: [u8; AES_GCM_256_IV_LENGTH],
 }
 
 impl AesGcm256CryptoInfo {
-    pub fn new(key: &[u8], iv: &[u8]) -> anyhow::Result<Self> {
+    pub fn new(in_key: &[u8], in_iv: &[u8]) -> anyhow::Result<Self> {
         anyhow::ensure!(
-            key.len() == AES_GCM_256_KEY_LENGTH,
+            in_key.len() == AES_GCM_256_KEY_LENGTH,
             "Invalid key length for AesGcm256: {}",
-            key.len()
+            in_key.len()
         );
         anyhow::ensure!(
-            iv.len() == AES_GCM_256_IV_LENGTH,
+            in_iv.len() == AES_GCM_256_IV_LENGTH,
             "Invalid iv length for AesGcm256: {}",
-            iv.len()
+            in_iv.len()
         );
-        let mut info = AesGcm256CryptoInfo::default();
-        info.key.copy_from_slice(key);
-        info.iv.copy_from_slice(iv);
-        Ok(info)
+        let mut key = [0u8; AES_GCM_256_KEY_LENGTH];
+        let mut iv = [0u8; AES_GCM_256_IV_LENGTH];
+        key.copy_from_slice(in_key);
+        iv.copy_from_slice(in_iv);
+        Ok(AesGcm256CryptoInfo { key, iv })
     }
 
     pub fn decrypt(&self, in_out: &mut Vec<u8>) -> anyhow::Result<()> {
@@ -45,33 +46,45 @@ impl AesGcm256CryptoInfo {
     }
 }
 
+impl Default for AesGcm256CryptoInfo {
+    fn default() -> Self {
+        let mut key = [0u8; AES_GCM_256_KEY_LENGTH];
+        let mut iv = [0u8; AES_GCM_256_IV_LENGTH];
+        let mut rng = rand::thread_rng();
+        rng.fill_bytes(&mut key);
+        rng.fill_bytes(&mut iv);
+        AesGcm256CryptoInfo { key, iv }
+    }
+}
+
 const AES_GCM_128_KEY_LENGTH: usize = 16;
 const AES_GCM_128_IV_LENGTH: usize = 12;
 
-#[derive(Default, Debug, Serialize, Deserialize)]
+#[derive(Clone, Debug)]
 pub struct AesGcm128CryptoInfo {
     pub key: [u8; AES_GCM_128_KEY_LENGTH],
     pub iv: [u8; AES_GCM_128_IV_LENGTH],
 }
 
 impl AesGcm128CryptoInfo {
-    pub fn new(key: &[u8], iv: &[u8]) -> anyhow::Result<Self> {
+    pub fn new(in_key: &[u8], in_iv: &[u8]) -> anyhow::Result<Self> {
         anyhow::ensure!(
-            key.len() == AES_GCM_128_KEY_LENGTH,
+            in_key.len() == AES_GCM_128_KEY_LENGTH,
             "Invalid key length for AesGcm128: {}",
-            key.len()
+            in_key.len()
         );
 
         anyhow::ensure!(
-            iv.len() == AES_GCM_128_IV_LENGTH,
+            in_iv.len() == AES_GCM_128_IV_LENGTH,
             "Invalid iv length for AesGcm128: {}",
-            iv.len()
+            in_iv.len()
         );
 
-        let mut info = AesGcm128CryptoInfo::default();
-        info.key.copy_from_slice(key);
-        info.iv.copy_from_slice(iv);
-        Ok(info)
+        let mut key = [0u8; AES_GCM_128_KEY_LENGTH];
+        let mut iv = [0u8; AES_GCM_128_IV_LENGTH];
+        key.copy_from_slice(in_key);
+        iv.copy_from_slice(in_iv);
+        Ok(AesGcm128CryptoInfo { key, iv })
     }
 
     pub fn decrypt(&self, in_out: &mut Vec<u8>) -> anyhow::Result<()> {
@@ -86,34 +99,104 @@ impl AesGcm128CryptoInfo {
     }
 }
 
+impl Default for AesGcm128CryptoInfo {
+    fn default() -> Self {
+        let mut key = [0u8; AES_GCM_128_KEY_LENGTH];
+        let mut iv = [0u8; AES_GCM_128_IV_LENGTH];
+        let mut rng = rand::thread_rng();
+        rng.fill_bytes(&mut key);
+        rng.fill_bytes(&mut iv);
+        AesGcm128CryptoInfo { key, iv }
+    }
+}
+
 const TEACLAVE_FILE_ROOT_KEY_128_LENGTH: usize = 16;
 
-#[derive(Default, Debug, Serialize, Deserialize)]
+#[derive(Clone, Debug)]
 pub struct TeaclaveFileRootKey128 {
-    pub key: [u8; 16],
+    pub key: [u8; TEACLAVE_FILE_ROOT_KEY_128_LENGTH],
 }
 
 impl TeaclaveFileRootKey128 {
-    pub fn new(key: &[u8]) -> anyhow::Result<Self> {
+    pub fn new(in_key: &[u8]) -> anyhow::Result<Self> {
         anyhow::ensure!(
-            key.len() == TEACLAVE_FILE_ROOT_KEY_128_LENGTH,
+            in_key.len() == TEACLAVE_FILE_ROOT_KEY_128_LENGTH,
             "Invalid key length for teaclave_file_root_key_128: {}",
-            key.len()
+            in_key.len()
         );
-        let mut info = TeaclaveFileRootKey128::default();
-        info.key.copy_from_slice(key);
-        Ok(info)
+        let mut key = [0u8; TEACLAVE_FILE_ROOT_KEY_128_LENGTH];
+        key.copy_from_slice(in_key);
+        Ok(TeaclaveFileRootKey128 { key })
+    }
+}
+
+impl Default for TeaclaveFileRootKey128 {
+    fn default() -> Self {
+        let mut key = [0u8; TEACLAVE_FILE_ROOT_KEY_128_LENGTH];
+        let mut rng = rand::thread_rng();
+        rng.fill_bytes(&mut key);
+        TeaclaveFileRootKey128 { key }
     }
 }
 
-#[derive(Debug, Serialize, Deserialize)]
-#[serde(rename_all(deserialize = "snake_case"))]
+#[derive(Clone, Debug)]
 pub enum TeaclaveFileCryptoInfo {
     AesGcm128(AesGcm128CryptoInfo),
     AesGcm256(AesGcm256CryptoInfo),
     TeaclaveFileRootKey128(TeaclaveFileRootKey128),
 }
 
+impl TeaclaveFileCryptoInfo {
+    pub fn new(schema: &str, key: &[u8], iv: &[u8]) -> anyhow::Result<Self> {
+        let info = match schema {
+            "aes_gcm_128" => {
+                let info = AesGcm128CryptoInfo::new(key, iv)?;
+                TeaclaveFileCryptoInfo::AesGcm128(info)
+            }
+            "aes_gcm_256" => {
+                let info = AesGcm256CryptoInfo::new(key, iv)?;
+                TeaclaveFileCryptoInfo::AesGcm256(info)
+            }
+            "teaclave_file_root_key_128" => {
+                anyhow::ensure!(
+                    iv.is_empty(),
+                    "IV is not empty for teaclave_file_root_key_128"
+                );
+                let info = TeaclaveFileRootKey128::new(key)?;
+                TeaclaveFileCryptoInfo::TeaclaveFileRootKey128(info)
+            }
+            _ => anyhow::bail!("Invalid crypto schema: {}", schema),
+        };
+        Ok(info)
+    }
+
+    pub fn schema(&self) -> String {
+        match self {
+            TeaclaveFileCryptoInfo::AesGcm128(_) => "aes_gcm_128".to_string(),
+            TeaclaveFileCryptoInfo::AesGcm256(_) => "aes_gcm_256".to_string(),
+            TeaclaveFileCryptoInfo::TeaclaveFileRootKey128(_) => {
+                "teaclave_file_root_key_128".to_string()
+            }
+        }
+    }
+
+    pub fn key_iv(&self) -> (Vec<u8>, Vec<u8>) {
+        match self {
+            TeaclaveFileCryptoInfo::AesGcm128(crypto) => (crypto.key.to_vec(), 
crypto.iv.to_vec()),
+            TeaclaveFileCryptoInfo::AesGcm256(crypto) => (crypto.key.to_vec(), 
crypto.iv.to_vec()),
+            TeaclaveFileCryptoInfo::TeaclaveFileRootKey128(crypto) => {
+                (crypto.key.to_vec(), Vec::new())
+            }
+        }
+    }
+}
+
+impl Default for TeaclaveFileCryptoInfo {
+    fn default() -> Self {
+        
TeaclaveFileCryptoInfo::TeaclaveFileRootKey128(TeaclaveFileRootKey128::default())
+    }
+}
+
 fn make_teaclave_aad() -> ring::aead::Aad<[u8; 8]> {
     let bytes = [0u8; 8];
     ring::aead::Aad::from(bytes)
diff --git a/types/src/worker.rs b/types/src/worker.rs
index 5dcb10c..4051b41 100644
--- a/types/src/worker.rs
+++ b/types/src/worker.rs
@@ -1,12 +1,7 @@
-#[cfg(feature = "mesalock_sgx")]
-use std::prelude::v1::*;
-
-use serde::{Deserialize, Serialize};
 use std::collections::HashMap;
 use std::format;
 use std::io::{self, Read};
-
-use protected_fs::ProtectedFile;
+use std::prelude::v1::*;
 
 #[cfg(feature = "mesalock_sgx")]
 use std::untrusted::fs::File;
@@ -17,19 +12,29 @@ use std::fs::File;
 use anyhow;
 
 use crate::TeaclaveFileCryptoInfo;
+use protected_fs::ProtectedFile;
+use serde::{Deserialize, Serialize};
 
-#[derive(Serialize, Deserialize, Debug)]
-#[serde(rename_all(deserialize = "snake_case"))]
+#[macro_export]
+macro_rules! hashmap {
+    ($( $key: expr => $val: expr ),*) => {{
+         let mut map = ::std::collections::HashMap::new();
+         $( map.insert($key, $val); )*
+         map
+    }}
+}
+
+#[derive(Debug)]
 pub enum TeaclaveExecutorSelector {
     Native,
     Python,
 }
 
-impl std::convert::TryFrom<String> for TeaclaveExecutorSelector {
+impl std::convert::TryFrom<&str> for TeaclaveExecutorSelector {
     type Error = anyhow::Error;
 
-    fn try_from(selector: String) -> anyhow::Result<Self> {
-        let sel = match selector.as_ref() {
+    fn try_from(selector: &str) -> anyhow::Result<Self> {
+        let sel = match selector {
             "python" => TeaclaveExecutorSelector::Python,
             "native" => TeaclaveExecutorSelector::Native,
             _ => anyhow::bail!("Invalid executor selector: {}", selector),
@@ -69,19 +74,64 @@ impl io::Read for ReadBuffer {
     }
 }
 
-#[derive(Serialize, Deserialize, Debug)]
+#[derive(Clone, Debug)]
 pub struct TeaclaveWorkerFileInfo {
     pub path: std::path::PathBuf,
     pub crypto_info: TeaclaveFileCryptoInfo,
 }
 
-fn read_all_bytes<P: AsRef<std::path::Path>>(path: P) -> 
anyhow::Result<Vec<u8>> {
+impl TeaclaveWorkerFileInfo {
+    pub fn new(
+        path: impl std::convert::Into<std::path::PathBuf>,
+        crypto_info: TeaclaveFileCryptoInfo,
+    ) -> Self {
+        TeaclaveWorkerFileInfo {
+            path: path.into(),
+            crypto_info,
+        }
+    }
+}
+
+pub fn read_all_bytes(path: impl AsRef<std::path::Path>) -> 
anyhow::Result<Vec<u8>> {
     let mut content = Vec::new();
     let mut file = File::open(path)?;
     file.read_to_end(&mut content)?;
     Ok(content)
 }
 
+fn teaclave_file_with_bytes(path: &str, bytes: &[u8]) -> 
anyhow::Result<TeaclaveWorkerFileInfo> {
+    let crypto_info = TeaclaveFileCryptoInfo::default();
+    let file_info = TeaclaveWorkerFileInfo::new(path, crypto_info);
+    let mut f = file_info.get_writable_io()?;
+    f.write_all(bytes)?;
+    Ok(file_info)
+}
+
+pub fn convert_plaintext_file(src: &str, dst: &str) -> 
anyhow::Result<TeaclaveWorkerFileInfo> {
+    let bytes = read_all_bytes(src)?;
+    teaclave_file_with_bytes(dst, &bytes)
+}
+
+pub fn convert_encrypted_file(
+    src: TeaclaveWorkerFileInfo,
+    dst: &str,
+) -> anyhow::Result<TeaclaveWorkerFileInfo> {
+    let plain_text = match &src.crypto_info {
+        TeaclaveFileCryptoInfo::AesGcm128(crypto) => {
+            let mut bytes = read_all_bytes(src.path)?;
+            crypto.decrypt(&mut bytes)?;
+            bytes
+        }
+        TeaclaveFileCryptoInfo::AesGcm256(crypto) => {
+            let mut bytes = read_all_bytes(src.path)?;
+            crypto.decrypt(&mut bytes)?;
+            bytes
+        }
+        TeaclaveFileCryptoInfo::TeaclaveFileRootKey128(_) => return Ok(src),
+    };
+    teaclave_file_with_bytes(dst, &plain_text)
+}
+
 impl TeaclaveWorkerFileInfo {
     pub fn get_readable_io(&self) -> anyhow::Result<Box<dyn io::Read>> {
         let readable: Box<dyn io::Read> = match &self.crypto_info {
@@ -115,12 +165,17 @@ impl TeaclaveWorkerFileInfo {
     }
 }
 
-#[derive(Serialize, Deserialize, Debug)]
+#[derive(Debug)]
 pub struct TeaclaveWorkerFileRegistry {
-    #[serde(flatten)]
     pub entries: HashMap<String, TeaclaveWorkerFileInfo>,
 }
 
+impl TeaclaveWorkerFileRegistry {
+    pub fn new(entries: HashMap<String, TeaclaveWorkerFileInfo>) -> Self {
+        TeaclaveWorkerFileRegistry { entries }
+    }
+}
+
 impl<T> std::convert::TryFrom<HashMap<String, T>> for 
TeaclaveWorkerFileRegistry
 where
     T: std::convert::TryInto<TeaclaveWorkerFileInfo, Error = anyhow::Error>,
@@ -156,11 +211,23 @@ where
 
 #[derive(Serialize, Deserialize, Debug)]
 pub struct TeaclaveFunctionArguments {
-    #[serde(flatten)]
     pub args: HashMap<String, String>,
 }
 
 impl TeaclaveFunctionArguments {
+    pub fn new<K, V>(input: &HashMap<K, V>) -> Self
+    where
+        K: std::string::ToString,
+        V: std::string::ToString,
+    {
+        let args = input.iter().fold(HashMap::new(), |mut acc, (k, v)| {
+            acc.insert(k.to_string(), v.to_string());
+            acc
+        });
+
+        TeaclaveFunctionArguments { args }
+    }
+
     pub fn try_get<T: std::str::FromStr>(&self, key: &str) -> 
anyhow::Result<T> {
         self.args
             .get(key)
@@ -181,7 +248,7 @@ impl TeaclaveFunctionArguments {
     }
 }
 
-#[derive(Serialize, Deserialize, Debug)]
+#[derive(Debug)]
 pub struct WorkerInvocation {
     pub runtime_name: String,
     pub executor_type: TeaclaveExecutorSelector, // "native" | "python"
diff --git a/worker/src/function/context.rs b/worker/src/function/context.rs
index 791ca04..f0ac184 100644
--- a/worker/src/function/context.rs
+++ b/worker/src/function/context.rs
@@ -219,11 +219,11 @@ pub fn rtc_close_handle(f: FileHandle) -> 
anyhow::Result<()> {
 #[cfg(feature = "enclave_unit_test")]
 pub mod tests {
     use super::*;
-    use crate::hashmap;
     use crate::runtime::RawIoRuntime;
     use std::path::PathBuf;
     use std::str::FromStr;
     use teaclave_test_utils::*;
+    use teaclave_types::hashmap;
     use teaclave_types::AesGcm256CryptoInfo;
     use teaclave_types::TeaclaveFileCryptoInfo;
     use teaclave_types::TeaclaveWorkerFileInfo;
diff --git a/worker/src/function/gbdt_training.rs 
b/worker/src/function/gbdt_training.rs
index 4406380..6b67fe6 100644
--- a/worker/src/function/gbdt_training.rs
+++ b/worker/src/function/gbdt_training.rs
@@ -35,6 +35,9 @@ use gbdt::gradient_boost::GBDT;
 #[derive(Default)]
 pub struct GbdtTraining;
 
+static IN_DATA: &str = "training_data";
+static OUT_MODEL: &str = "trained_model";
+
 impl TeaclaveFunction for GbdtTraining {
     fn execute(
         &self,
@@ -52,7 +55,7 @@ impl TeaclaveFunction for GbdtTraining {
         let training_optimization_level: u8 = 
args.try_get("training_optimization_level")?;
 
         // read input
-        let training_file = runtime.open_input("training_data")?;
+        let training_file = runtime.open_input(IN_DATA)?;
         let mut train_dv = parse_training_data(training_file, feature_size)?;
         let data_size = train_dv.len();
 
@@ -75,7 +78,7 @@ impl TeaclaveFunction for GbdtTraining {
         let model_json = serde_json::to_string(&gbdt_train_mod)?;
 
         // save the model to output
-        let mut model_file = runtime.create_output("trained_model")?;
+        let mut model_file = runtime.create_output(OUT_MODEL)?;
         model_file.write_all(model_json.as_bytes())?;
 
         let summary = format!("Trained {} lines of data.", data_size);
@@ -127,69 +130,54 @@ pub mod tests {
     use super::*;
     use teaclave_test_utils::*;
 
+    use std::untrusted::fs;
+
+    use teaclave_types::hashmap;
+    use teaclave_types::TeaclaveFileCryptoInfo;
+    use teaclave_types::TeaclaveFunctionArguments;
+    use teaclave_types::TeaclaveWorkerFileInfo;
+    use teaclave_types::TeaclaveWorkerFileRegistry;
+
     use crate::function::TeaclaveFunction;
     use crate::runtime::RawIoRuntime;
-    use std::untrusted::fs;
-    use teaclave_types::{TeaclaveFunctionArguments, 
TeaclaveWorkerFileRegistry};
 
     pub fn run_tests() -> bool {
         run_tests!(test_gbdt_training, test_gbdt_parse_training_data,)
     }
 
     fn test_gbdt_training() {
-        let args_json = r#"
-            {
-                "feature_size": "4",
-                "max_depth": "4",
-                "iterations": "100",
-                "shrinkage": "0.1",
-                "feature_sample_ratio": "1.0",
-                "data_sample_ratio": "1.0",
-                "min_leaf_size": "1",
-                "loss": "LAD",
-                "training_optimization_level": "2"
-            }
-        "#;
-
-        let input_json = r#"
-            {
-                "training_data": {
-                    "path": "test_cases/gbdt_training/train.txt",
-                    "crypto_info": {
-                        "aes_gcm128": {
-                            "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
13, 14, 15],
-                            "iv": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-                        }
-                    }
-                }
-            }
-        "#;
-
-        let output_json = r#"
-            {
-                "trained_model": {
-                    "path": "test_cases/gbdt_training/training_model.txt.out",
-                    "crypto_info": {
-                        "aes_gcm128": {
-                            "key": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 
13, 14, 15],
-                            "iv": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
-                        }
-                    }
-                }
-            }
-        "#;
-
-        let func_args: TeaclaveFunctionArguments = 
serde_json::from_str(&args_json).unwrap();
-        let input_files: TeaclaveWorkerFileRegistry = 
serde_json::from_str(&input_json).unwrap();
-        let output_files: TeaclaveWorkerFileRegistry = 
serde_json::from_str(&output_json).unwrap();
+        let func_args = TeaclaveFunctionArguments::new(&hashmap!(
+            "feature_size"  => "4",
+            "max_depth"     => "4",
+            "iterations"    => "100",
+            "shrinkage"     => "0.1",
+            "feature_sample_ratio" => "1.0",
+            "data_sample_ratio" => "1.0",
+            "min_leaf_size" => "1",
+            "loss"          => "LAD",
+            "training_optimization_level" => "2"
+        ));
+
+        let plain_input = "test_cases/gbdt_training/train.txt";
+        let plain_output = "test_cases/gbdt_training/training_model.txt.out";
+        let expected_output = "test_cases/gbdt_training/expected_model.txt";
+
+        let input_files = TeaclaveWorkerFileRegistry::new(hashmap!(
+            IN_DATA.to_string() =>
+            TeaclaveWorkerFileInfo::new(plain_input, 
TeaclaveFileCryptoInfo::default())
+        ));
+
+        let output_files = TeaclaveWorkerFileRegistry::new(hashmap!(
+            OUT_MODEL.to_string() =>
+            TeaclaveWorkerFileInfo::new(plain_output, 
TeaclaveFileCryptoInfo::default())
+        ));
+
         let runtime = Box::new(RawIoRuntime::new(input_files, output_files));
 
         let function = GbdtTraining;
         let summary = function.execute(runtime, func_args).unwrap();
         assert_eq!(summary, "Trained 120 lines of data.");
 
-        let plain_output = "test_cases/gbdt_training/training_model.txt.out";
-        let expected_output = "test_cases/gbdt_training/expected_model.txt";
         let result = fs::read_to_string(&plain_output).unwrap();
         let expected = fs::read_to_string(&expected_output).unwrap();
         assert_eq!(&result[..], &expected[..]);
@@ -198,6 +186,9 @@ pub mod tests {
     fn test_gbdt_parse_training_data() {
         let line = "4.8,3.0,1.4,0.3,3.0";
         let result = parse_data_line(&line, 4);
-        assert_eq!(result.is_ok(), true);
+        assert!(result.is_ok());
+
+        let result = parse_data_line(&line, 3);
+        assert!(result.is_err());
     }
 }
diff --git a/worker/src/function/mesapy.rs b/worker/src/function/mesapy.rs
index 7cfe721..b386c21 100644
--- a/worker/src/function/mesapy.rs
+++ b/worker/src/function/mesapy.rs
@@ -100,15 +100,6 @@ impl TeaclaveFunction for Mesapy {
     }
 }
 
-#[macro_export]
-macro_rules! hashmap {
-    ($( $key: expr => $val: expr ),*) => {{
-         let mut map = ::std::collections::HashMap::new();
-         $( map.insert($key, $val); )*
-         map
-    }}
-}
-
 #[cfg(feature = "enclave_unit_test")]
 pub mod tests {
     use super::*;
@@ -116,9 +107,7 @@ pub mod tests {
 
     use crate::function::TeaclaveFunction;
     use crate::runtime::RawIoRuntime;
-    use std::path::PathBuf;
-    use std::str::FromStr;
-    use teaclave_types::AesGcm256CryptoInfo;
+    use teaclave_types::hashmap;
     use teaclave_types::TeaclaveFileCryptoInfo;
     use teaclave_types::TeaclaveFunctionArguments;
     use teaclave_types::TeaclaveWorkerFileInfo;
@@ -129,7 +118,7 @@ pub mod tests {
     }
 
     fn test_mesapy() {
-        let py_args = hashmap!("--name" => "Teaclave");
+        let py_args = TeaclaveFunctionArguments::new(&hashmap!("--name" => 
"Teaclave"));
         let py_payload = "
 import sys
 def entrypoint(argv):
@@ -137,18 +126,12 @@ def entrypoint(argv):
     print argv[1]
 ";
 
-        let input = PathBuf::from_str("test_cases/mesapy/input.txt").unwrap();
-        let output = 
PathBuf::from_str("test_cases/mesapy/output.txt").unwrap();
+        let input = "test_cases/mesapy/input.txt";
+        let output = "test_cases/mesapy/output.txt";
 
-        let input_info = TeaclaveWorkerFileInfo {
-            path: input,
-            crypto_info: 
TeaclaveFileCryptoInfo::AesGcm256(AesGcm256CryptoInfo::default()),
-        };
+        let input_info = TeaclaveWorkerFileInfo::new(input, 
TeaclaveFileCryptoInfo::default());
 
-        let output_info = TeaclaveWorkerFileInfo {
-            path: output,
-            crypto_info: 
TeaclaveFileCryptoInfo::AesGcm256(AesGcm256CryptoInfo::default()),
-        };
+        let output_info = TeaclaveWorkerFileInfo::new(output, 
TeaclaveFileCryptoInfo::default());
 
         let input_files = TeaclaveWorkerFileRegistry {
             entries: hashmap!("in_f1".to_string() => input_info),


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to