A game that we all played when we were young is probably hide and seek. When we grow up, we come up with new variants like scavenger hunt. Did you ever want to play scavenger hunt in real life but too tired to set up props? Or perhaps you can make your friends guess where you are by posting a selfie and giving hints to your exact location. I present to you, the hide and seek game. Where your browser with access to your location data, can leverage Cape to enable sharing of your secret location, without anyone but you being any the wiser.
This walkthrough shows how this application is developed using technology developed at Cape Privacy. It showcases the power of data encryption without the hassle of key management. After the walkthrough, you will have a web application that you can interact with anywhere.
Playing around with it
A example of this app has already been deployed to codesandbox.
In this web application you can click the hide button. That will encrypt your current coordinates that you can send to your friend!
Once your friend receives the coordinates, they can copy it into the destination text box and click the seek button which will tell him how far or close they are to your current location.
Why use Cape for this solution
Through the use of Cape encrypt, we could encrypt your location and allow you to share your data with someone else without them knowing where it is. This data is only accessible for the function you intend it for and can’t be accessed by anyone else. All of the overhead of encryption and key management has been handled by the SDK, making it easy to leverage for the application.
Implementation
The python source code for this project can be seen here on github.
This example is run using the Cape-JS and the function is deployed using Cape CLI.
Setup Dependencies
Make sure you have CLI installed by running:
curl -fsSL https://raw.githubusercontent.com/capeprivacy/cli/main/install.sh | sh
Create the Function
The function is relatively simple but showcases a couple of nuances in how it is invoked.
What’s interesting about the current cape_handler function is that the handler expects to take two user-provided inputs, one after the other. It will persist the first input on disk until the invocation is complete.
This allows the handler function to take an encrypted input first and a non-encrypted input after. Achieving the desired result of mixed encrypted and unencrypted inputs.
Calling this function from an external source would take on the form of:
- Connect (connects to the enclave)
- Invoke (send first input)
- Invoke (send second input)
- Close (close the connection to the invocation, resetting the state of the function)
app.py
import math
import string
from unicodedata import name
import json
import geopy
from geopy.distance import geodesic as GD
FILE_PATH = "./secret.json"
def open_secret(path=FILE_PATH):
with open(path) as f:
try:
data = json.load(f)
except Exception:
return None
return data
def store_secret(data, path=FILE_PATH):
with open(path, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=4)
# Function needs to check if the coordinates match the one that was provided.
def cape_handler(arg):
user_input = json.loads(arg)
# use file cache instead
secret = open_secret()
if secret == None:
# Store the current input as secret
store_secret(user_input)
else:
# Calculate the difference between the user secret and the current input.
user_loco = (float(user_input["latitude"]), float(user_input["longitude"]))
secret_loco = (float(secret["latitude"]), float(secret["longitude"]))
distance = GD(secret_loco, user_loco).m
if distance < 100:
ret = f"Congrats you found the treasure!"
elif distance < 10000:
ret = f"Getting closer! still {distance} meters away"
else:
ret = f"Not even close! still {distance} meters away"
return ret
requirements.txt
geographiclib==1.52
geopy==2.2.0
secret.json
Just an empty file that can be created by:
touch seek/secret.json
At this point the seek directory should look like:
requirements.txt
seek/
- app.py
- secret.json (empty file)
Before deploying this function, we have to install the dependencies with the function by calling (from the parent directory of [seek]):
pip install -r requirements.txt --target seek/
This will install the dependencies required to run the function.
Next step will be to deploy this function to Cape using the Cape CLI tool.
Deploy the Function
To deploy the function use the cape binary that has been downloaded from the CLI step and run:
cape login
This will give you a prompt to open up a browser and login to your github account.
To deploy the function run:
cape deploy seek/
You will see an output like the following:
Function ID ➜ YmoDB35PKxZS9v6eaU84YR
Function Checksum ➜ 6b6d1c8b21f896269554cf633da084b25b49706a8efb41463687f353e0395171
Then run
cape token <FUNCTION_ID> --function-checksum <FUNCTION _CHECKSUM> -o json > seek.json
Interacting with the Function via the React App
To use the deployed function, we will use Cape-JS and use the encrypt and invoke methods defined through the Cape client.
To call the function from the example React App, simply update the following file to reflect the functionID and functionToken from seek.json obtained in the previous script to the file here.
Final Thoughts
This project showcases the power of Cape to share data amongst different parties in a purely encrypted format. It also showcases a workaround for stateful execution and temporary data persistence from within the enclave. These methods allow the developer using Cape SDKs to expand the capabilities of their functions and interact with them from various platforms.
Top comments (0)