You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by ms...@apache.org on 2020/08/04 21:12:42 UTC
[incubator-teaclave] branch master updated: Add a new builtin
function for face detection (#399)
This is an automated email from the ASF dual-hosted git repository.
mssun pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave.git
The following commit(s) were added to refs/heads/master by this push:
new 47237ea Add a new builtin function for face detection (#399)
47237ea is described below
commit 47237ea2d82b4c7d1af8388a76ed8732a31827da
Author: yc-huang <yc...@gmail.com>
AuthorDate: Tue Aug 4 14:12:28 2020 -0700
Add a new builtin function for face detection (#399)
---
.drone.yml | 92 +++++------
CONTRIBUTORS.md | 1 +
cmake/scripts/test.sh | 1 +
cmake/tomls/Cargo.sgx_trusted_lib.toml | 2 +-
docker/build.ubuntu-1804.sgx-2.9.1.Dockerfile | 2 +-
docker/build.ubuntu-1804.sgx-dcap-1.6.Dockerfile | 2 +-
examples/python/builtin_face_detection.py | 119 ++++++++++++++
examples/python/requirments.txt | 5 +
executor/Cargo.toml | 2 +
executor/src/builtin.rs | 6 +-
function/Cargo.toml | 2 +
function/README.md | 2 +
function/src/face_detection.rs | 179 +++++++++++++++++++++
function/src/lib.rs | 3 +
tests/fixtures/functions/face_detection/input.jpg | Bin 0 -> 262603 bytes
tests/fixtures/functions/face_detection/output.jpg | Bin 0 -> 265729 bytes
third_party/crates-sgx | 2 +-
tool/enclave/src/lib.rs | 2 +-
18 files changed, 369 insertions(+), 53 deletions(-)
diff --git a/.drone.yml b/.drone.yml
index 3cdd28f..02538ad 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -3,24 +3,24 @@ name: sgx-debug-ubuntu-1804
steps:
- name: prepare
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- . /opt/sgxsdk/environment
- mkdir -p build
- cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON ..
- name: check
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make check
- name: compile
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make VERBOSE=1 -j2
- name: test
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
environment:
AS_ALGO: sgx_epid
AS_URL: https://api.trustedservices.intel.com:443
@@ -58,26 +58,26 @@ name: sgx-dcap-debug-ubuntu-1804
steps:
- name: prepare
- image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.2
commands:
- . /root/.cargo/env
- . /opt/sgxsdk/environment
- mkdir -p build
- cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON -DDCAP=ON ..
- name: check
- image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.2
commands:
- . /root/.cargo/env
- cd build && make check
- name: compile
- image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.2
commands:
- . /root/.cargo/env
- . /opt/sgxsdk/environment
- sed -i 's/ias_root_ca_cert/dcap_root_ca_cert/' config/build.config.toml
- cd build && make VERBOSE=1 -j2
- name: test
- image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-dcap-1.6:0.1.2
environment:
AS_ALGO: sgx_ecdsa
AS_URL: https://localhost:8080
@@ -125,24 +125,24 @@ name: sgx-release-ubuntu-1804
steps:
- name: prepare
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- . /opt/sgxsdk/environment
- mkdir -p build
- cd build && cmake -DCMAKE_BUILD_TYPE=Release -DTEST_MODE=OFF ..
- name: check
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make check
- name: compile
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make VERBOSE=1 -j2
- name: test
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
privileged: true
environment:
AS_ALGO: sgx_epid
@@ -178,24 +178,24 @@ name: sim-debug-ubuntu-1804
steps:
- name: prepare
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- . /opt/sgxsdk/environment
- mkdir -p build
- cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DSGX_SIM_MODE=ON -DTEST_MODE=ON ..
- name: check
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make check
- name: compile
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make VERBOSE=1 -j2
- name: test
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
environment:
AS_ALGO: sgx_epid
AS_URL: https://api.trustedservices.intel.com:443
@@ -217,24 +217,24 @@ name: sim-release-ubuntu-1804
steps:
- name: prepare
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- . /opt/sgxsdk/environment
- mkdir -p build
- cd build && cmake -DCMAKE_BUILD_TYPE=Release -DSGX_SIM_MODE=ON -DTEST_MODE=OFF ..
- name: check
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make check
- name: compile
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make VERBOSE=1 -j2
- name: test
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make run-examples
@@ -249,23 +249,23 @@ node:
# steps:
# - name: prepare
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - mkdir -p build
# - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DTEST_MODE=ON ..
# - name: check
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make check
# - name: compile
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make VERBOSE=1 -j2
# - name: test
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# environment:
# AS_ALGO: sgx_epid
# AS_URL: https://api.trustedservices.intel.com:443
@@ -301,23 +301,23 @@ node:
# steps:
# - name: prepare
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - mkdir -p build
# - cd build && cmake -DTEST_MODE=ON ..
# - name: check
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make check
# - name: compile
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make VERBOSE=1 -j2
# - name: test
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# privileged: true
# environment:
# AS_ALGO: sgx_epid
@@ -353,23 +353,23 @@ node:
# steps:
# - name: prepare
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - mkdir -p build
# - cd build && cmake -DTEST_MODE=ON ..
# - name: check
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make check
# - name: compile
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && cmake -DCMAKE_BUILD_TYPE=Debug -DSGX_SIM_MODE=ON .. && make VERBOSE=1 -j2
# - name: test
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make run-tests
@@ -384,23 +384,23 @@ node:
# steps:
# - name: prepare
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - mkdir -p build
# - cd build && cmake ..
# - name: check
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make check
# - name: compile
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && cmake -DSGX_SIM_MODE=ON -DTEST_MODE=ON .. && make VERBOSE=1 -j2
# - name: test
-# image: teaclave/teaclave-build-ubuntu-1604:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1604:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make run-tests
@@ -415,19 +415,19 @@ name: lint
steps:
- name: prepare
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- . /opt/sgxsdk/environment
- mkdir -p build
- cd build && cmake -DRUSTFLAGS="-D warnings" -DTEST_MODE=ON ..
- name: check
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make check
- name: clippy
- image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+ image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
commands:
- . /root/.cargo/env
- cd build && make CLP=1
@@ -442,24 +442,24 @@ node:
# steps:
# - name: prepare
-# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
# commands:
# - . /root/.cargo/env
# - mkdir -p build
# - cd build && cmake -DCMAKE_BUILD_TYPE=DEBUG -DCOV=ON -DTEST_MODE=ON ..
# - name: check
-# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
# commands:
# - . /root/.cargo/env
# - cd build && make check
# - name: compile
-# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
# commands:
# - . /root/.cargo/env
# - export RUSTFLAGS="-D warnings"
# - cd build && make VERBOSE=1 -j2
# - name: test
-# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
# environment:
# AS_ALGO: sgx_epid
# AS_URL: https://api.trustedservices.intel.com:443
@@ -478,7 +478,7 @@ node:
# - cd build && make run-tests
# - name: coverage
# failure: ignore
-# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
# commands:
# - cd build && make cov
# - bash -c "bash <(curl -s https://codecov.io/bash) -f intermediate/cov.info"
@@ -510,13 +510,13 @@ node:
# steps:
# - name: prepare
-# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
# commands:
# - . /root/.cargo/env
# - mkdir -p build
# - cd build && cmake ..
# - name: doc
-# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.1
+# image: teaclave/teaclave-build-ubuntu-1804-sgx-2.9.1:0.1.2
# failure: ignore
# commands:
# - . /root/.cargo/env
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 451ceda..2831348 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -77,6 +77,7 @@ List of external contributors of Teaclave and Teaclave SGX SDK (in alphabetical
- [piotr-roslaniec](https://github.com/piotr-roslaniec)
- [rebol0x6c](https://github.com/rebol0x6c)
- [volcano](https://github.com/volcano0dr)
+ - [yc-huang](https://github.com/yc-huang)
- [zEqueue](https://github.com/z1queue)
More people tracked in GitHub:
diff --git a/cmake/scripts/test.sh b/cmake/scripts/test.sh
index 5c39793..04388f4 100755
--- a/cmake/scripts/test.sh
+++ b/cmake/scripts/test.sh
@@ -172,6 +172,7 @@ run_examples() {
python3 builtin_private_join_and_compute.py
python3 builtin_ordered_set_intersect.py
python3 builtin_rsa_sign.py
+ python3 builtin_face_detection.py
popd
# kill all background services
diff --git a/cmake/tomls/Cargo.sgx_trusted_lib.toml b/cmake/tomls/Cargo.sgx_trusted_lib.toml
index 24d0b67..3837025 100644
--- a/cmake/tomls/Cargo.sgx_trusted_lib.toml
+++ b/cmake/tomls/Cargo.sgx_trusted_lib.toml
@@ -50,7 +50,7 @@ gbdt = { git = "https://github.com/mesalock-linux/gbdt-rs", branch
getrandom = { git = "https://github.com/mesalock-linux/getrandom-sgx" }
crc = { git = "https://github.com/mesalock-linux/crc-rs-sgx" }
# gif = { git = "https://github.com/mesalock-linux/image-gif-sgx" }
-# image = { git = "https://github.com/mesalock-linux/image-sgx" }
+image = { git = "https://github.com/mesalock-linux/image-sgx" }
# inflate = { git = "https://github.com/mesalock-linux/inflate-sgx" }
itoa = { git = "https://github.com/mesalock-linux/itoa-sgx" }
# jpeg-decoder = { git = "https://github.com/mesalock-linux/jpeg-decoder-sgx" }
diff --git a/docker/build.ubuntu-1804.sgx-2.9.1.Dockerfile b/docker/build.ubuntu-1804.sgx-2.9.1.Dockerfile
index f9a6266..cf32ba9 100644
--- a/docker/build.ubuntu-1804.sgx-2.9.1.Dockerfile
+++ b/docker/build.ubuntu-1804.sgx-2.9.1.Dockerfile
@@ -78,7 +78,7 @@ RUN apt-get update && apt-get install -q -y \
curl \
python3-pip
-RUN pip3 install pyopenssl toml cryptography yapf
+RUN pip3 install pyopenssl toml cryptography yapf requests Pillow
# clean up apt caches
diff --git a/docker/build.ubuntu-1804.sgx-dcap-1.6.Dockerfile b/docker/build.ubuntu-1804.sgx-dcap-1.6.Dockerfile
index e7c0c4e..361c3d4 100644
--- a/docker/build.ubuntu-1804.sgx-dcap-1.6.Dockerfile
+++ b/docker/build.ubuntu-1804.sgx-dcap-1.6.Dockerfile
@@ -81,7 +81,7 @@ RUN apt-get update && apt-get install -q -y \
iproute2 \
python3-pip
-RUN pip3 install pyopenssl toml cryptography yapf
+RUN pip3 install pyopenssl toml cryptography yapf requests Pillow
# clean up apt caches
diff --git a/examples/python/builtin_face_detection.py b/examples/python/builtin_face_detection.py
new file mode 100644
index 0000000..c7c56ec
--- /dev/null
+++ b/examples/python/builtin_face_detection.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python3
+
+import os
+import sys
+import base64
+import json
+
+from PIL import Image, ImageDraw
+import requests
+
+from teaclave import (AuthenticationService, FrontendService, OwnerList,
+ AuthenticationClient, FrontendClient, DataMap,
+ FunctionInput)
+from utils import (AUTHENTICATION_SERVICE_ADDRESS, FRONTEND_SERVICE_ADDRESS,
+ AS_ROOT_CA_CERT_PATH, ENCLAVE_INFO_PATH, USER_ID,
+ USER_PASSWORD)
+
+
+class BuiltinFaceDetectionExample:
+ def __init__(self, user_id, user_password):
+ self.user_id = user_id
+ self.user_password = user_password
+
+ def detect_face(self, image_base64):
+ client = AuthenticationService(
+ AUTHENTICATION_SERVICE_ADDRESS, AS_ROOT_CA_CERT_PATH,
+ ENCLAVE_INFO_PATH).connect().get_client()
+
+ print("[+] registering user")
+ client.user_register(self.user_id, self.user_password)
+
+ print("[+] login")
+ token = client.user_login(self.user_id, self.user_password)
+
+ client = FrontendService(FRONTEND_SERVICE_ADDRESS,
+ AS_ROOT_CA_CERT_PATH,
+ ENCLAVE_INFO_PATH).connect().get_client()
+ metadata = {"id": self.user_id, "token": token}
+ client.metadata = metadata
+
+ print("[+] registering function")
+ function_id = client.register_function(
+ name="builtin-face-detection",
+ description="Native Face Detection Function",
+ executor_type="builtin",
+ inputs=[],
+ arguments=[
+ "image_base64", "min_face_size", "score_thresh",
+ "pyramid_scale_factor", "slide_window_step_x",
+ "slide_window_step_y"
+ ])
+
+ print("[+] creating task")
+ task_id = client.create_task(function_id=function_id,
+ function_arguments={
+ "image_base64": image_base64,
+ "min_face_size": 20,
+ "score_thresh": 2.0,
+ "pyramid_scale_factor": 0.8,
+ "slide_window_step_x": 4,
+ "slide_window_step_y": 4
+ },
+ inputs_ownership=[],
+ executor="builtin")
+
+ print("[+] invoking task")
+ client.invoke_task(task_id)
+
+ print("[+] getting result")
+ result = client.get_task_result(task_id)
+ print("[+] done")
+
+ return bytes(result)
+
+
+def main():
+ img_file_name = 'in.jpg'
+
+ if not os.path.isfile(img_file_name):
+ image_url = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6e/Solvay_conference_1927.jpg/1400px-Solvay_conference_1927.jpg'
+ print("[+] retrieving image from url:", image_url)
+
+ response = requests.get(image_url).content
+ with open(img_file_name, 'wb') as file:
+ file.write(response)
+ print("[+] image saved to", img_file_name)
+ else:
+ print("[+] using cached file", img_file_name)
+
+ with open(img_file_name, 'rb') as fin:
+ image_data = fin.read()
+ base64_encoded_data = base64.b64encode(image_data).decode('utf-8')
+
+ example = BuiltinFaceDetectionExample(USER_ID, USER_PASSWORD)
+
+ rt = example.detect_face(base64_encoded_data)
+
+ print("[+] function return:", rt)
+
+ bboxes = json.loads(rt)
+
+ img = Image.open(img_file_name).convert('RGB')
+ draw = ImageDraw.Draw(img)
+
+ for bbox in bboxes:
+ box = bbox['bbox']
+ draw.rectangle([
+ box['x'], box['y'], box['x'] + box['height'],
+ box['y'] + box['width']
+ ],
+ outline='red',
+ width=2)
+
+ img.save('out.jpg', 'JPEG')
+ print("[+] detection result saved to out.jpg")
+
+
+if __name__ == '__main__':
+ main()
diff --git a/examples/python/requirments.txt b/examples/python/requirments.txt
new file mode 100644
index 0000000..6f3b748
--- /dev/null
+++ b/examples/python/requirments.txt
@@ -0,0 +1,5 @@
+pyopenssl
+toml
+cryptography
+requests
+Pillow
diff --git a/executor/Cargo.toml b/executor/Cargo.toml
index b86d4c2..df458ed 100644
--- a/executor/Cargo.toml
+++ b/executor/Cargo.toml
@@ -37,6 +37,7 @@ full_builtin_function = [
"builtin_private_join_and_compute",
"builtin_ordered_set_intersect",
"builtin_rsa_sign",
+ "builtin_face_detection",
]
builtin_echo = []
@@ -48,6 +49,7 @@ builtin_online_decrypt = []
builtin_private_join_and_compute = []
builtin_ordered_set_intersect = []
builtin_rsa_sign = []
+builtin_face_detection = []
[dependencies]
log = { version = "0.4.6", features = ["release_max_level_info"] }
diff --git a/executor/src/builtin.rs b/executor/src/builtin.rs
index 677e782..510db29 100644
--- a/executor/src/builtin.rs
+++ b/executor/src/builtin.rs
@@ -19,8 +19,8 @@
use std::prelude::v1::*;
use teaclave_function::{
- Echo, GbdtPredict, GbdtTrain, LogisticRegressionPredict, LogisticRegressionTrain,
- OnlineDecrypt, OrderedSetIntersect, PrivateJoinAndCompute, RsaSign,
+ Echo, FaceDetection, GbdtPredict, GbdtTrain, LogisticRegressionPredict,
+ LogisticRegressionTrain, OnlineDecrypt, OrderedSetIntersect, PrivateJoinAndCompute, RsaSign,
};
use teaclave_types::{FunctionArguments, FunctionRuntime, TeaclaveExecutor};
@@ -58,6 +58,8 @@ impl TeaclaveExecutor for BuiltinFunctionExecutor {
OrderedSetIntersect::NAME => OrderedSetIntersect::new().run(arguments, runtime),
#[cfg(feature = "builtin_rsa_sign")]
RsaSign::NAME => RsaSign::new().run(arguments, runtime),
+ #[cfg(feature = "builtin_face_detection")]
+ FaceDetection::NAME => FaceDetection::new().run(arguments, runtime),
_ => bail!("Function not found."),
}
}
diff --git a/function/Cargo.toml b/function/Cargo.toml
index deb3abd..ccb65a7 100644
--- a/function/Cargo.toml
+++ b/function/Cargo.toml
@@ -36,6 +36,8 @@ itertools = { version = "0.8.0", default-features = false }
ring = { version = "0.16.5" }
base64 = { version = "0.10.1" }
hex = { version = "0.4.0" }
+image = { version = "0.22.4" }
+rustface = { version = "0.1.2", features = [ "include_default_model" ] }
teaclave_types = { path = "../types" }
teaclave_crypto = { path = "../crypto" }
diff --git a/function/README.md b/function/README.md
index b856b57..af104d1 100644
--- a/function/README.md
+++ b/function/README.md
@@ -25,6 +25,8 @@ Currently, we have these built-in functions:
elements in the intersection. Users should calculate hash values of each item
and upload them as a sorted list.
- `builtin-rsa-sign`: Signing data with RSA key.
+ - `builtin-face-detection`: an implementation of Funnel-Structured cascade,
+ which is designed for real-time multi-view face detection.
The function arguments are in JSON format and can be serialized to a Rust struct
very easily. You can learn more about supported arguments in the implementation
diff --git a/function/src/face_detection.rs b/function/src/face_detection.rs
new file mode 100644
index 0000000..5acf5e1
--- /dev/null
+++ b/function/src/face_detection.rs
@@ -0,0 +1,179 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+extern crate base64;
+extern crate image;
+#[cfg(feature = "mesalock_sgx")]
+extern crate rustface;
+
+use std::prelude::v1::*;
+
+use std::convert::TryFrom;
+use teaclave_types::{FunctionArguments, FunctionRuntime};
+
+#[derive(Default)]
+pub struct FaceDetection;
+
+#[derive(serde::Deserialize)]
+struct FaceDetectionArguments {
+ image_base64: String,
+ /// Set the size of the sliding window.
+ ///
+ /// The minimum size is constrained as no smaller than 20.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `wnd_size` is less than 20.
+ window_size: Option<u32>,
+ /// Set the sliding window step in horizontal and vertical directions.
+ ///
+ /// The steps should take positive values.
+ /// Usually a step of 4 is a reasonable choice.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `step_x` or `step_y` is less than or equal to 0.
+ slide_window_step_x: Option<u32>,
+ slide_window_step_y: Option<u32>,
+ /// Set the minimum size of faces to detect.
+ ///
+ /// The minimum size is constrained as no smaller than 20.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `min_face_size` is less than 20.
+ min_face_size: Option<u32>,
+ /// Set the maximum size of faces to detect.
+ ///
+ /// The maximum face size actually used is computed as the minimum among:
+ /// user specified size, image width, image height.
+ max_face_size: Option<u32>,
+ /// Set the factor between adjacent scales of image pyramid.
+ ///
+ /// The value of the factor lies in (0.1, 0.99). For example, when it is set as 0.5,
+ /// an input image of size w x h will be resized to 0.5w x 0.5h, 0.25w x 0.25h, 0.125w x 0.125h, etc.
+ ///
+ /// # Panics
+ ///
+ /// Panics if `scale_factor` is less than 0.01 or greater than 0.99
+ pyramid_scale_factor: Option<f32>,
+ /// Set the score threshold of detected faces.
+ ///
+ /// Detections with scores smaller than the threshold will not be returned.
+ /// Typical threshold values include 0.95, 2.8, 4.5. One can adjust the
+ /// threshold based on his or her own test set.
+ ///
+ /// Smaller values result in more detections (possibly increasing the number of false positives),
+ /// larger values result in fewer detections (possibly increasing the number of false negatives).
+ ///
+ /// # Panics
+ ///
+ /// Panics if `thresh` is less than or equal to 0.
+ score_thresh: Option<f64>,
+}
+
+impl TryFrom<FunctionArguments> for FaceDetectionArguments {
+ type Error = anyhow::Error;
+
+ fn try_from(arguments: FunctionArguments) -> Result<Self, Self::Error> {
+ use anyhow::Context;
+ serde_json::from_str(&arguments.into_string()).context("Cannot deserialize arguments")
+ }
+}
+
+impl FaceDetection {
+ pub const NAME: &'static str = "builtin-face-detection";
+
+ pub fn new() -> Self {
+ Default::default()
+ }
+
+ pub fn run(
+ &self,
+ arguments: FunctionArguments,
+ _runtime: FunctionRuntime,
+ ) -> anyhow::Result<String> {
+ let arguments = FaceDetectionArguments::try_from(arguments)?;
+ let image_base64 = arguments.image_base64;
+ let vec = base64::decode(&image_base64).unwrap();
+ let bytes: &[u8] = &vec;
+ let img = image::load_from_memory(&bytes)?;
+
+ let mut detector = rustface::create_default_detector()?;
+ if let Some(window_size) = arguments.window_size {
+ detector.set_window_size(window_size);
+ }
+ if let (Some(step_x), Some(step_y)) =
+ (arguments.slide_window_step_x, arguments.slide_window_step_y)
+ {
+ detector.set_slide_window_step(step_x, step_y);
+ }
+ if let Some(min_face_size) = arguments.min_face_size {
+ detector.set_min_face_size(min_face_size);
+ }
+ if let Some(max_face_size) = arguments.max_face_size {
+ detector.set_max_face_size(max_face_size);
+ }
+ if let Some(pyramid_scale_factor) = arguments.pyramid_scale_factor {
+ detector.set_pyramid_scale_factor(pyramid_scale_factor);
+ }
+ if let Some(score_thresh) = arguments.score_thresh {
+ detector.set_score_thresh(score_thresh);
+ }
+
+ let faces = rustface::detect_faces(&mut *detector, img);
+ let result = serde_json::to_string(&faces)?;
+
+ Ok(result)
+ }
+}
+
+#[cfg(feature = "enclave_unit_test")]
+pub mod tests {
+ use super::*;
+ use serde_json::json;
+ use std::untrusted::fs;
+ use teaclave_runtime::*;
+ use teaclave_test_utils::*;
+ use teaclave_types::*;
+
+ pub fn run_tests() -> bool {
+ run_tests!(test_face_detection)
+ }
+
+ fn test_face_detection() {
+ let input = "fixtures/functions/face_detection/input.jpg";
+ let image_base64 = base64::encode(&fs::read(input).unwrap());
+ let arguments = FunctionArguments::from_json(json!({
+ "image_base64": image_base64,
+ "min_face_size": 20,
+ "score_thresh": 2.0,
+ "pyramid_scale_factor": 0.8,
+ "slide_window_step_x": 4,
+ "slide_window_step_y": 4
+ }))
+ .unwrap();
+
+ let input_files = StagedFiles::new(hashmap!());
+ let output_files = StagedFiles::new(hashmap!());
+ let runtime = Box::new(RawIoRuntime::new(input_files, output_files));
+
+ let result = FaceDetection::new().run(arguments, runtime).unwrap();
+ let json_result: serde_json::Value = serde_json::from_str(&result).unwrap();
+ assert_eq!(json_result.as_array().unwrap().len(), 28);
+ }
+}
diff --git a/function/src/lib.rs b/function/src/lib.rs
index 1ea110f..a733017 100644
--- a/function/src/lib.rs
+++ b/function/src/lib.rs
@@ -23,6 +23,7 @@ extern crate sgx_tstd as std;
use std::prelude::v1::*;
mod echo;
+mod face_detection;
mod gbdt_predict;
mod gbdt_train;
mod logistic_regression_predict;
@@ -33,6 +34,7 @@ mod private_join_and_compute;
mod rsa_sign;
pub use echo::Echo;
+pub use face_detection::FaceDetection;
pub use gbdt_predict::GbdtPredict;
pub use gbdt_train::GbdtTrain;
pub use logistic_regression_predict::LogisticRegressionPredict;
@@ -58,6 +60,7 @@ pub mod tests {
private_join_and_compute::tests::run_tests(),
ordered_set_intersect::tests::run_tests(),
rsa_sign::tests::run_tests(),
+ face_detection::tests::run_tests(),
)
}
}
diff --git a/tests/fixtures/functions/face_detection/input.jpg b/tests/fixtures/functions/face_detection/input.jpg
new file mode 100644
index 0000000..a7a8431
Binary files /dev/null and b/tests/fixtures/functions/face_detection/input.jpg differ
diff --git a/tests/fixtures/functions/face_detection/output.jpg b/tests/fixtures/functions/face_detection/output.jpg
new file mode 100644
index 0000000..7d7d319
Binary files /dev/null and b/tests/fixtures/functions/face_detection/output.jpg differ
diff --git a/third_party/crates-sgx b/third_party/crates-sgx
index 7b0f647..76012b5 160000
--- a/third_party/crates-sgx
+++ b/third_party/crates-sgx
@@ -1 +1 @@
-Subproject commit 7b0f647835e67a61304717af13a8fa934c919ce1
+Subproject commit 76012b501ac94046f227a7e905f49b95e556f354
diff --git a/tool/enclave/src/lib.rs b/tool/enclave/src/lib.rs
index 0bf1c67..4fb13f3 100644
--- a/tool/enclave/src/lib.rs
+++ b/tool/enclave/src/lib.rs
@@ -60,7 +60,7 @@ fn attestation(raw_json_input: &RawJsonInput) -> anyhow::Result<()> {
};
println!("Remote Attestation Report:");
println!("{}", serde_json::to_string_pretty(&attn_report)?);
- println!("");
+ println!();
println!("ISV Enclave Quote Body:");
println!("{:?}", sgx_quote_body);
Ok(())
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org