Skip to content
This repository was archived by the owner on Mar 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions DevConDemo/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## Comprehensive skeleton for DevCon Demo

This Folder is used for final draft of DevCon demo flow before migrating to the actual DevCon demo [repo](https://github.com/ZKStats/mpc-demo-infra)

Note that we're working with 256-bit integer, resulting in 320-bit prime number, which is greater than 256 bit. Hence need to write MOD = -DGFP_MOD_SZ=5 into CONFIG.mine

**Test Flow**
Expand Down
72 changes: 3 additions & 69 deletions ExternalDemo/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
This Folder is Used for validating ideas/necessary properties for our application for DevCon.
## First draft of DevCon Demo

This Folder is used for validating ideas/necessary properties for our application for DevCon, mainly on save & load private shares.

The computation function in this demo is the same as bankers_bonus aka determine the highest bonus value

Expand Down Expand Up @@ -83,71 +85,3 @@ Array, Matrix, multiArray, sfix, sint, Compiler.ml.FixAveragePool2d, Compiler.ml
```

3.2 Now the clients can interact as 2.1 and 2.2 (Yet no way to save and crash this running, due to the reason mentioned above in Limitation/constraints section)

**Legacy from Originial ReadMe**

The ExternalIO directory contains an example of managing I/O between
external client processes and parties running MP-SPDZ engines. These
instructions assume that MP-SPDZ has been built as per the [project
readme](../README.md).

## Working Examples

[bankers-bonus-client.cpp](../ExternalIO/bankers-bonus-client.cpp) and
[bankers-bonus-client.py](../ExternalIO/bankers-bonus-client.py) act as a
client to [bankers_bonus.mpc](../Programs/Source/bankers_bonus.mpc)
and demonstrates sending input and receiving output as described by
[Damgård et al.](https://eprint.iacr.org/2015/1006) The computation
allows up to eight clients to input a number and computes the client
with the largest input. You can run the C++ code as follows from the main
directory:

```
make bankers-bonus-client.x
./compile.py bankers_bonus 1
Scripts/setup-ssl.sh <nparties>
Scripts/setup-clients.sh 3
PLAYERS=<nparties> Scripts/<protocol>.sh bankers_bonus-1 &
./bankers-bonus-client.x 0 <nparties> 100 0 &
./bankers-bonus-client.x 1 <nparties> 200 0 &
./bankers-bonus-client.x 2 <nparties> 50 1
```

`<protocol>` can be any arithmetic protocol (e.g., `mascot`) but not a
binary protocol (e.g., `yao`).
This should output that the winning id is 1. Note that the ids have to
be incremental, and the client with the highest id has to input 1 as
the last argument while the others have to input 0 there. Furthermore,
`<nparties>` refers to the number of parties running the computation
not the number of clients, and `<protocol>` can be the name of
protocol script. The setup scripts generate the necessary SSL
certificates and keys. Therefore, if you run the computation on
different hosts, you will have to distribute the `*.pem` files.

For the Python client, make sure to install
[gmpy2](https://pypi.org/project/gmpy2), and run
`ExternalIO/bankers-bonus-client.py` instead of
`bankers-bonus-client.x`.

## I/O MPC Instructions

### Connection Setup

1. [Listen for clients](https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.library.listen_for_clients)
2. [Accept client connections](https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.library.accept_client_connection)
3. [Close client connections](https://mp-spdz.readthedocs.io/en/latest/instructions.html#Compiler.instructions.closeclientconnection)

### Data Exchange

Only the `sint` methods used in the example are documented here, equivalent methods are available for other data types. See [the reference](https://mp-spdz.readthedocs.io/en/latest/Compiler.html#module-Compiler.types).

1. [Public value from client](https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.types.regint.read_from_socket)
2. [Secret value from client](https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.types.sint.receive_from_client)
3. [Reveal secret value to clients](https://mp-spdz.readthedocs.io/en/latest/Compiler.html#Compiler.types.sint.reveal_to_clients)

## Client-Side Interface

The example uses the `Client` class implemented in
`ExternalIO/Client.hpp` to handle the communication, see
[this reference](https://mp-spdz.readthedocs.io/en/latest/io.html#reference) for
documentation.
84 changes: 53 additions & 31 deletions ExternalStats/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,41 @@
**Statistics operations with client Example**
This folder is for doing client interface with statistics function where client does nothing but getting the output.
## Benchmarking stats operations with client interface

Here, we consider 2 servers with private data doing MPC together, only to output to the client.
We input private data of these 2 servers in Player-Data/Input-P0-0, and Player-Data/Input-P1-0. For example, you can just put 0 1 2 3 170 160 152 180 in Player-Data/Input-P0-0, and 3 0 4 5 50 60 70 100 in Player-Data/Input-P1-0
This folder is for comparing & contrast the calculation of statistics function with and without client interface where client does nothing but getting the output. See more about client-interface[here](https://mp-spdz.readthedocs.io/en/latest/client-interface.html#client-interface)

Run the following commands for client version, here for example of 2 computing servers and one client
### How to run

**Setup**

We Input private data to computing servers (server parties that perform MPC calculation) in Player-Data. For example, if we consider using 2 servers, we can put 0 1 2 3 170 160 152 180 in Player-Data/Input-P0-0, and 3 0 4 5 50 60 70 100 in Player-Data/Input-P1-0

**Case 1 : 2 Computing Servers (without any client)**

Run the following commands (as shown in main README of the repo )

```
./compile.py stats-noclient
Scripts/../semi-party.x 0 stats-noclient -pn 17090 -h localhost -N 2 -OF .
Scripts/../semi-party.x 1 stats-noclient -pn 17090 -h localhost -N 2 -OF .
```

Note that here, we only delivers output to the 2nd client by modifying stats-noclient.mpc a bit as seen in comment, to make its behavior close to client interface

**Case 2 : 3 Computing Servers (without any client)**

Run the following commands (as shown in main README of the repo )

```
./compile.py stats-noclient
Scripts/../semi-party.x 0 stats-noclient -pn 17090 -h localhost -N 3 -OF .
Scripts/../semi-party.x 1 stats-noclient -pn 17090 -h localhost -N 3 -OF .
Scripts/../semi-party.x 2 stats-noclient -pn 17090 -h localhost -N 3 -OF .
```

Note that here, we only delivers output to the 2nd client by modifying stats-noclient.mpc a bit as seen in comment, to make its behavior close to client interface

**Case 3: 2 Computing Servers + 1 Client**

Run the following commands

```
make stats-client.x
Expand All @@ -19,44 +50,35 @@ Commands above do the following

- make stats-client.x : Run Makefile to handle stats-client.cpp in folder ExternalStats
- ./compile.py stats-client: Compile stats-client.mpc file in Programs/Source
- Scripts/setup-ssl.sh 2: Create triple shares for each party (spdz engine). 2 means 2 computing servers
- Scripts/setup-clients.sh 1: Create SSL keys and certificates for clients. 1 means 1 client
- Scripts/setup-ssl.sh 2: Create triple shares for each party (spdz engine). 2 indicates 2 computing servers
- Scripts/setup-clients.sh 1: Create SSL keys and certificates for clients. 1 indicates 1 client
- PLAYERS=2 Scripts/semi.sh stats-client: Run server engines
- ./stats-client.x 0 2 1: Run client. 0 means client index 0, 2 means number of party, 1 means finish (dont need to wait for more clients)

Run the following commands for non-client version (as shown in main README of the repo) Here in case of 2 computating servers

```
./compile.py stats-noclient
Scripts/../semi-party.x 0 stats-noclient -pn 17090 -h localhost -N 2 -OF .
Scripts/../semi-party.x 1 stats-noclient -pn 17090 -h localhost -N 2 -OF .
```

**BenchMark**
We compare this 2 servers + 1 client implementation with naive 2 servers in stats-noclient.mpc in Programs/Source and get the following results
- ./stats-client.x 0 2 1: Run client. 0 indicates client index 0, 2 indicates the number of party, 1 indicates finish (dont need to wait for more clients)

With Client
### BenchMark

- Data sent = 3.28978 MB in ~158 rounds (party 0 only; use '-v' for more details)
Global data sent = 6.59185 MB (all parties)

Without Client.
**Case 1 : 2 Computing Servers (without any client)**

- Data sent = 3.28973 MB in ~154 rounds (party 0 only; use '-v' for more details)
Global data sent = 6.59176 MB (all parties)

Hence, the overhead is very small. Again the trust assumption of client-interface only depends on the computing servers

Now we compare this 2 servers + 1 client implementation with naive 3 servers in stats-noclient.mpc (that only delivers output to the 2nd client, we just modify stats-noclient.mpc a bit as seen in comment) in Programs/Source and get the following results
**Case 2 : 3 Computing Servers (without any client)**

- Data sent = 25.6026 MB in ~305 rounds (party 2 only; use '-v' for more details)
Global data sent = 76.9298 MB (all parties)

Hence, by introducing another computating server for the sake of just getting output costs so so much, but we get more secure trusted assumption, since we can always trust ourselves.
**Case 3 : 2 Computing Servers + 1 Client**

- Data sent = 3.28978 MB in ~158 rounds (party 0 only; use '-v' for more details)
Global data sent = 6.59185 MB (all parties)

Comparing case 1 with case 3, we can see that the overhead is very small, which makes sense since the trust assumption of client-interface only depends on the computing servers

Now considering case 2, we can see that introducing another computating server for the sake of just getting output costs so so much. This trade-off comes from the fact that we get more secure trusted assumption, since we can always trust ourselves.

**Issues**
### Some weird behavior

- However, when we run without client version with main.py, the amount of data skyrocket to - Data sent = 4.77346 MB in ~214 rounds (party 0 only; use '-v' for more details)
- When we run without client version with main.py, the amount of data skyrocket to - Data sent = 4.77346 MB in ~214 rounds (party 0 only; use '-v' for more details)
Global data sent = 9.55921 MB (all parties)
This is likely due to

Expand All @@ -68,7 +90,7 @@ Hence, by introducing another computating server for the sake of just getting ou

inside main.py

**Observation**
## Notes

- We use sfix instead of sint in our program because stats operation likely results in floating number, hence the result the client receives is already multiplied by the scale. For example, if the result is 55., the client will receive 55\*2^16 ~ 3604480
- Anyway, by default, sfix is also faster than sint: https://github.com/data61/MP-SPDZ/issues/1400#issuecomment-2107550939
Loading
Loading