code for the simulator.
```
- qansel-source-base.zip
+ rosado-source-base.zip
```
To compile it, navigate to the folder it installed within and
run the following commands within that folder.
```sh
- mkdir qansel
- mv *qansel-source-base.zip qansel
- cd qansel
- unzip *qansel-source-base.zip
+ mkdir rosado
+ mv *rosado-source-base.zip qansel
+ cd rosado
+ unzip *rosado-source-base.zip
make
```
-If you are compiling for a device which cannot support
-hardware acceleration, then you can use `make simple` which
-will build the program with those features stripped out.
+You can also use `make install` after running `make` to
+install it.
## Usage
+To convert a CLI program to a web API, it must be designed such that
+it takes in its input as standard input and provides its output as
+standard output.
+This project expects a MySQL/MariaDB installation with a schema
+titled RosadoAPI. The first time the program is executed, it will
+automatically create the necessary tables within this schema. Make
+sure that the password to login to the database is stored as the
+first line of text in the configuration file in the path below.
+The second line is used to set the port number.
+```
+ /etc/rosadoapi.conf
+```
+The API uses two tables. The first table is ServiceInfo which is
+used to set up a CLI program to be used as an API. Below is the
+structure for this table.
-Many example programs that can be executed inside of QAnsel can
-be found by clicking the `tree` link at the top fo the page and
-then navigating to the `examples` folder. Simply click on one of
-the examples in order to see the source code.
+```sql
-## Usage
-The QAnsel simulator expects programs to be written in a language
-similar to OpenQASM 2.0. These programs must be piped into QAnsel
-as standard input and the simulation results will be displayed as
-standard output. Below is an example using a here document.
+```
+
+The `service` field is the name of the service and also corresponds
+to the path that must be pinged to access it. For example, if the
+service is named `myapi` and hosted at `localhost` then to access
+this service, the client will need to ping `localhost/myapi`.
+
+The `path` field is the actual full path of the executable program.
+The `parameters` field is any command line parameters that should be
+passed into the program when it is called.
+
+The second table is the `AuthInfo` table. This is related to
+authentication for users trying to ping the API. Below is the
+structure for this table.
+
+```sql
+
+```
+
+The `service` field must correspond to a `service` in the `ServiceInfo`
+table. The `username` field is the name of a registered user allowed
+to access an API. The `authkey` is their authentication token which is
+also used for encryption and decryption. The `timeout` value is how
+long the user is able to run an application for. Different users can
+be authorized to run programs for longer periods of time.
+
+To generate a unique `authkey` for a user, use the command below.
```sh
- $ ./QAnsel << EOF
- > qreg q[2];
- > creg c[2];
- > h q[0];
- > cx q[0], q[1];
- > measure q[0] -> c[0];
- > measure q[1] -> c[1];
- > sample c;
- > EOF
- 00: 50.7%
- 01: 0.0%
- 10: 0.0%
- 11: 49.3%
+ openssl rand -hex 32
```
-Please use the `-?` flag to see a help document.
+Communication with the API service is encrypted with ChaCha20-HMAC
+This means it cannot be pinged using plaintext. To ping it and get a
+response, the request must be encrypted using ChaCha20-HMAC, and
+the response also must be decrypted in the same way.
-## Special Hardware
+Below are variables that will need to be populated in order to
+ping the API service.
-To enable a hardware random number generator, the `-r`
-flag must be used. This flag will select the hardware
-random number generator based on an order of precedence.
-The order is as follows.
+- `$srvc`: The service to send a request to.
+- `$user`: The user requesting the service.
+- `$auth`: The authentication key.
+- `$rqst`: The request data.
+- `$sess`: A session identifier.
-1. Quantis-PCIe-40M
-2. TrueRNG V3
-3. Secure Key Technology
+Below is the beginnings of a Bash script defining these values
+grabbing most from command line arguments except for the request
+itself which comes from standard input as well as the session ID
+which is randomly generated.
-To enable GPU acceleration, the `-oX` flag has to be
-set replacing `X` with an optimization level equal to
-4 or greater.
+```sh
+ srvc=$1
+ user=$2
+ auth=$3
+ read rqst
+ sess=$(openssl rand -hex 12)
+```
-It is recommended that you run a simple program with the
-`-v` flag which will produce output stating which hardware
-devices were actually found and enabled.
+The next step is to generate the request data which is computed
+simply by taking the plaintext request and encrypting it with
+ChaCha20 using the authentication key. Then, a digest will also
+need to be computed for the message which allows the server to
+verify the message has not been tampered with. This must be
+calculated from the plaintext message using HMAC-SHA256.
-QAnsel can handle up to 16 qubits, however, qubit counts
-greater than 14 will not fit into most consumer-end GPUs.
-The amount of qubits that can fit is limited by the
-amount of VRAM. The GPU must have at least 8 GB for 14
-qubits, 16 GB for 15 qubits, and 48 GB for 16 qubits.
+Both of these values also need to be encoded as base64. Below
+is a Bash script that generates the body and digest for the
+request.
-## API and Web Interface
+```sh
+ data=$(echo -n "$rqst" | openssl enc -chacha20 -K $auth -iv 00000000$sess | base64 | tr -d '\n')
+ dgst=$(echo -n "$data" | base64 -d | openssl sha256 -hex -mac HMAC -macopt hexkey:$auth | cut -d '=' -f 2 | xargs)
+```
-There is a drag-and-drop interface that runs in the browser
-that can be found by clicking the `tree` button and navigating
-to the `bin` folder and downloading the following file.
+The username, session, data, and digest then can be combined
+to form the post request in `application/x-www-form-urlencoded`
+format. Below is an example of how to produce such a request
+and store the response in variable in Bash.
+```sh
+ resp=$(curl -s -X POST -d "user=$user&sess=$sess&dgst=$dgst&data=$data" "$srvr/$srvc")
```
- qansel-source-web.zip
+
+The response from the server is in a similar format, so it
+should first be parsed into different response variables.
+
+```sh
+ for param in user sess dgst data
+ do
+ eval r$param=$(echo "$resp" | sed -e "s/.*$param=//" -e "s/&.*//") 2> /dev/null
+ done
```
-This web front end expects to connect to an API. The API
-service is handled through FoleoAPI. Please see the FoleoAPI
-project in order to set up this service.
+The response message needs to be validated by recomputing
+the digest and verifying it matches the received digest
+and verifying the user matches the requested user.
+
+```sh
+ if [ "$user" != "$ruser" ]
+ then
+ echo "Invalid response: user mismatch."
+ exit 1
+ fi
+ dgst=$(echo -n "$rdata" | base64 -d | openssl sha256 -hex -mac HMAC -macopt hexkey:$auth | cut -d '=' -f 2 | xargs)
+ if [ "$dgst" != "$rdgst" ]
+ then
+ echo "Invalid response: digest mismatch."
+ exit 1
+ fi
+```
-Once FoleoAPI is running, a ServiceInfo record will need to be
-added to the APIService schema. Below is an example of how this
-entry may look.
+Finally, once the response is received and verified, it
+can be decrypted using ChaCha20. ChaCha20 uses the same
+command to encrypt as it does to decrypt because it
+is a symmetrical cipher.
-```sql
- MariaDB [APIService]> select * from ServiceInfo;
- +----+---------+---------------------------------+-------------+
- | id | service | path | parameters |
- +----+---------+---------------------------------+-------------+
- | 1 | qansel | /fakepath/QAnsel | -q14 -o5 -r |
- +----+---------+---------------------------------+-------------+
+```
+ echo -n "$rdata" | base64 -d | openssl enc -d -chacha20 -K $auth -iv 00000000$rsess
```
-The `-qX` parameter is useful here as it allows one to cap
-the maximum qubit count allowed for the process in case the
-hardware running the simulator is not sufficient to handle large
-qubit counts. In this case, it is capped at 14 to make sure that
-programs that exceed the limitations of the GPU are rejected.
-
-The web interface expects an API key. The API key is formed in three
-parts `A:B:C` where `A` is the `APIService.AuthInfo.username`, `B` is
-the `APIService.AuthInfo.authkey`, and `C` is the URL which it needs
-to ping. It is important that the address does not contain `http://`
-or `https://`. For example, if the address is `http://example.com/api`,
-then `C` should simply be written as `example.com/api`.
-
-Once `A:B:C` is filled out, the entire thing needs to be converted to
-a base64 string. This can be done in JavaScript in the developer console
-in the web browser using the `btoa()` function. This final encoded string
-functions as the API key for the web interface. Any equal signs at the
-end of the API key should be removed.
-
-The web interface allows for appending the URL with `?apikey=` followed by
-an API key to auto fill the API key. This can be useful if the service is
-linked from another source (such as another website or an email) and will
-prevent the user from having to input the APIkey themselves.
-
-## Android
-
-The Android app version of this project merely is enclose a web view
-containing the web interface. This means it requires pinging a server
-running the API for it to work. It must be compiled using Android Studio.
+Please click the `tree` button on the top left of the
+page and click the `ping.sh` file to see this complete
+Bash script.