Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
valery-osheter committed Feb 13, 2019
2 parents e763adb + 62e4426 commit ce631fc
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 41 deletions.
63 changes: 32 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
# 1. Introduction to *blockchain-crypto-mpc*

**blockchain-crypto-mpc** is an open source library released by [Unbound
Tech](https://www.unboundtech.com/company/about/) that provides the
Tech](http://bit.ly/2SpMJ7W) that provides the
cryptographic foundation to resolve one of the hardest challenges
associated with crypto asset and blockchain applications: **The
protection of cryptographic signing keys and seed secrets**.



Unbound leverages [secure multiparty computation
(MPC)](https://www.unboundtech.com/technology-distributed-trust-platform/)
(MPC)](http://bit.ly/2Skw8m1)
for the protection and management of cryptographic keys and secrets, and
provides industry-grade MPC-based solutions for key management, key
protection and additional applications. The protocols were designed by
Expand All @@ -24,7 +24,6 @@ This readme includes an overview of this library, why it is important,
what it allows you to achieve, sample use cases, and how to use the
library (high level description).

This repository includes a tool for benchmarking the **blockchain-crypto-mpc** library. See [mpc_crypto_bench](https://github.com/unbound-tech/blockchain-crypto-mpc/blob/master/bench/README_MPC_Crypto_Bench.md) in the [bench](./bench) folder for more information.

# 2. Who Should Use it?

Expand Down Expand Up @@ -81,15 +80,11 @@ to use blockchain applications for all.**
**blockchain-crypto-mpc** includes a secure MPC implementation of the
following algorithms:

- 2-party ECDSA secp256k1: generation and signing

- 2-party ECDSA secp256k1: generation and signing
- 2-party EdDSA ed25519: generation and signing

- 2-party BIP32 (based on the [BIP32 specification](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)): generation, hard
derivation, and normal derivation

- Key share refresh

- Zero-knowledge backup

The source code is written in C++ and the external API in C. Detailed
Expand Down Expand Up @@ -131,16 +126,12 @@ them).

- Guaranteed non-repudiation; the application server cannot sign any
transaction without cooperation from the endpoint device.

- No single point of compromise: Compromising the seed or key material
requires the attacker to compromise both the server and the endpoint
simultaneously.

- No key or seed material ever appears in the clear throughout its
lifecycle, including while in use and during generation.

- Resilient to side-channel attacks.

- A model that empowers a crypto service provider to create an
excellent user experience by delivering a wallet service while
maintaining a very high security level and granting the users full
Expand All @@ -167,16 +158,12 @@ of both participants (and communication between them).

- Both devices must collaborate and approve any transaction. No single
device can approve a transaction.

- No single point of compromise: Compromising the seed or key material
requires the attacker to compromise both the laptop and the mobile
device simultaneously.

- No key or seed material ever appears in the clear throughout its
lifecycle, including while in use and during generation.

- Resilient to side-channel attacks.

- A model that empowers a wallet provider to create an excellent
user experience while maintaining a very high security level and
granting the users full control of their crypto assets.
Expand Down Expand Up @@ -223,7 +210,28 @@ the user's device and the Trustee Service, key share B is used by the user's dev
It's important to highlight that each of these pairs is completely
independent, each is effectively a backup of the same seed.

# 5. Technical Overview and Usage Guidelines
# 5. Benchmarking and Performance

This repository includes a two different tools for benchmarking the **blockchain-crypto-mpc** library.

1. MPC Crypto Bench - a tool written C++. See [mpc_crypto_bench](https://github.com/unbound-tech/blockchain-crypto-mpc/blob/master/bench/README.md) in the [bench](./bench) folder for more information.
2. MPC Crypto Python script. See [mpc_crypto](https://github.com/unbound-tech/blockchain-crypto-mpc/blob/master/python/README.md) in the [Python](./python) folder for more information.

MPC Crypto Bench tests the raw protocols, with no networking involved, while the MPC Crypto Python script is uses a client and server with actual networking.

Using the Python script, each command was run for 20 iterations and resulted in the following performance numbers:

| Algorithm | Command | Time (seconds) |
|-----------|----------|:--------------:|
| ECDSA | Generate | 0.945 |
| ECDSA | Sign | 0.015 |
| EdDSA | Generate | 0.003 |
| EdDSA | Sign | 0.003 |

The tests were run on a server with an Intel Xeon E5-2686 v4 (2.30 GHz) with 32 GB RAM.


# 6. Technical Overview and Usage Guidelines


Unbound's Blockchain Crypto MPC open source library provides functions
Expand All @@ -236,7 +244,7 @@ messages that are sent between the peers. Note that the actual
communication between peers is not included in this library.

![blockchain-crypto-mpc system](docs/images/os-system.png)
## 5.1 Definitions
## 6.1 Definitions


Blockchain Crypto MPC utilizes the following three structures:
Expand All @@ -245,10 +253,8 @@ Blockchain Crypto MPC utilizes the following three structures:
phase of the process or in any location at any time. A key share is
a piece of a key, which can be used by Unbound's MPC technology to
sign transactions.

2. **Message** -- Data that is passed to the other peer. The message
contains information about the action in progress.

3. **Context** -- Since each action, such as signing with a key,
involves multiple messages between the two peers, the status of the
action is preserved in a context.
Expand All @@ -257,27 +263,23 @@ The **key share**, **message**, and **context** contain varying amounts
of information depending on the type action, and therefore they are
structures.

## 5.2 Actions
## 6.2 Actions


The library provides the following actions:

- 2-party ECDSA secp256k1: generation and signing

- 2-party ECDSA secp256k1: generation and signing
- 2-party EdDSA ed25519: generation and signing

- 2-party BIP32 (based on the [BIP32 specification](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki)): generation, hard
derivation, and normal derivation

- Key share refresh

- Zero-knowledge backup

The library also provides mechanisms to handle serialization,
deserialization, and memory management for the key share, message, and
context structures.

## 5.3 System Flow
## 6.3 System Flow


The system flow is shown in the following figure:
Expand All @@ -301,11 +303,11 @@ peer can then do any necessary cleanup, such as freeing memory, or
copying an updated key share to storage.


### 5.3.1 Peer Roles
### 6.3.1 Peer Roles

Peer roles are determined by which peer initiates key generation. This peer must be used for any subsequent key operations, such as signing, derivation, and backup. For example, if peer A generates a key and then peer B wants to initiate a signing process, it should make a request to the peer A to start the process. When complete, the peer A can send the result to peer B. Peer B can verify this result with the *verify* function.

### 5.3.2 Detailed Flow
### 6.3.2 Detailed Flow

A detailed flow is described in the following procedure:

Expand All @@ -329,7 +331,7 @@ Throughout the entire process the same context should be used. If the context ne



### 5.3.3 Example Action
### 6.3.3 Example Action

An example of an ECDSA signing action is shown in the following figure.

Expand All @@ -341,4 +343,3 @@ for initialization. After initialization, each peer calls the
finished with the signing process. The signature, which is the result of
the signing process, is received by calling the final function,
**MPCCrypto_finalEcdsaSign()**, after which the signing process is done.

5 changes: 3 additions & 2 deletions bench/README_MPC_Crypto_Bench.md → bench/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@

## Build Instructions

First, compile the **blockchain-crypto-mpc** library as described in [build.md](https://github.com/unbound-tech/blockchain-crypto-mpc/blob/master/build.md).
This utility is compiled along with the **blockchain-crypto-mpc** library. Following the build instructions found [here](https://github.com/unbound-tech/blockchain-crypto-mpc/blob/master/build.md).

The executable is called **mpc_crypto_bench**.

Next, compile the benchmark utility by running `make`. The resulting executable is called **mpc_crypto_bench**.

## Command Line

Expand Down
19 changes: 19 additions & 0 deletions build.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,25 @@ The repository includes a simple makefile for building in Linux.
1. Review the makefile and modify as needed for your environment.
1. Run *make*.

For example, on Ubuntu Linux, use the following:
```sudo add-apt-repository ppa:webupd8team/java
sudo apt-get update
sudo apt-get install oracle-java8-installer
export JAVA_HOME=/usr/lib/jvm/java-8-oracle/
sudo apt install make
sudo apt install make-guile
sudo apt-get install gcc
sudo apt-get install g++
sudo apt-get install openssl
sudo apt-get install libssl-dev
git clone https://github.com/unbound-tech/blockchain-crypto-mpc.git
cd blockchain-crypto-mpc
make
export LD_LIBRARY_PATH=.
```

### Windows

The repository includes a Visual Studio solution.
Expand Down
46 changes: 46 additions & 0 deletions python/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# MPC Crypto Python Script

**MPC Crypto** is a Python script that can be used to accurately measure the speed of the **blockchain-crypto-mpc** library. It runs **blockchain-crypto-mpc** with a specified algorithm for a number of iterations and then returns that average runtime. The utility strives to measure the raw speed of the **blockchain-crypto-mpc** library, without any delays due to networking.

## Command Line

Before running the command line, set the following environment variable, pointing to wherever you compiled the **blockchain-crypto-mpc** library:

`LD_LIBRARY_PATH=/home/centos/Unbound/blockchain-crypto-mpc`

Run the utility with the following command:

```
python mpc_demo.py \
--type <algorithm> \
--command <sign|generate> \
--in_file <key filename>.bin \
--data_file <data filename>.dat \
--repeat <iterations>
```

where *algorithm* can be one of the following:

- ECDSA - for ECDSA
- EDDSA - for EdDSA

The value of *iterations* designates how many times to loop.

## Example

To run 10 iterations of ECDSA key signing:

```
python mpc_demo.py --type ECDSA --command sign --in_file key_share2.bin --data_file data.dat --repeat 5
ECDSA signing...
ok
ECDSA signing...
ok
ECDSA signing...
ok
ECDSA signing...
ok
ECDSA signing...
ok
Took 15.4986 ms on average
```
18 changes: 10 additions & 8 deletions python/mpc_demo.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ def run_sign(inShare, cryptoType):
with open(args.data_file, "rb") as f:
inData = f.read()
with obj:
obj.initSign(inData, True)
obj.initSign(inData)
exec_mpc_exchange(obj)
sig = obj.getSignResult()
print("ok")
Expand Down Expand Up @@ -183,19 +183,20 @@ def run_command(params):
def run_server():
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serversocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
serversocket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
serversocket.bind((args.host, args.port))
serversocket.listen(5)

global clientsocket
clientsocket, address = serversocket.accept()
params = argparse.Namespace()
while True:
header = clientsocket.recv(6)
header = clientsocket.recv(3*4)
if not header:
break
params.command = commands[int.from_bytes(header[:1], 'big')]
params.type = types[int.from_bytes(header[1:2], 'big')]
params.size = int.from_bytes(header[2:], 'big')
params.command = commands[struct.unpack("i", header[:4])[0]]
params.type = types[struct.unpack("i", header[4:8])[0]]
params.size = struct.unpack("i", header[8:])[0]
print(params)
out, outputFile = run_command(params)

Expand All @@ -208,10 +209,12 @@ def run_server():
def run_client():
global clientsocket
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
clientsocket.connect((args.host, args.port))

header = commands.index(args.command).to_bytes(
1, 'big') + types.index(args.type).to_bytes(1, 'big') + args.size.to_bytes(4, 'big')
header = struct.pack("i", commands.index(args.command)) + \
struct.pack("i", types.index(args.type)) + \
struct.pack("i", args.size)
startTime = datetime.datetime.now()
for _ in range(args.repeat):
clientsocket.send(header)
Expand Down Expand Up @@ -259,7 +262,6 @@ def run_client():
if not args.command or not args.type:
parser.error('Command and Type required for Client')
clientsocket = None

if args.server:
peer = SERVER
run_server()
Expand Down

0 comments on commit ce631fc

Please sign in to comment.