Hide And Seek
Published: 2022-11-24 19:59:05

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](https://codesandbox.io/s/hide-and-seek-us7feb?file=/src/App.tsx). 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/82ttp03bufzajds7bfwj.png)


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](https://github.com/capeprivacy/functions/tree/main/hide_and_seek).
This example is run using the [Cape-JS](https://github.com/capeprivacy/cape-js) and the function is deployed using [Cape CLI](https://github.com/capeprivacy/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](https://github.com/capeprivacy/functions/blob/main/hide_and_seek/seek/app.py#L27) 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: 
1. Connect (connects to the enclave)
2. Invoke (send first input)
3. Invoke (send second input)
4. Close (close the connection to the invocation, resetting the state of the function) 

**app.py**

```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](https://github.com/capeprivacy/cape-js) and use the **encrypt** and **invoke** methods defined through the Cape client.

To call the function from the example [React](https://reactjs.org/) App, simply update the following file to reflect the **functionID** and **functionToken** from **seek.json** obtained in the previous script to the file [here](https://codesandbox.io/s/hide-and-seek-us7feb?file=/src/App.tsx). 


## 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.