HERB is a Publicly Verifiable Random Beacon protocol described in this article. This repository is HERB implementation written in Golang as Cosmos application using Kyber library.
Publicly Verifiable Random Beacon protocol allows securely generating random numbers and any third party can validate results. HERB implementation is a blockchain application and HERB participants are users of this blockchain (not full nodes). After setup phase, all process will divide into rounds. Simplified implementation description:
- New round i is starting.
- Each participant sends the ciphertext share (encrypted random number) to the blockchain (as a transaction).
- After receiving t1 ciphertext share, the common ciphertext (encrypted sum of all sent random numbers) is being aggregated.
- Each participant sends decryption share to the blockchain (as a transaction).
- After receiving t2 decryption shares, the round is completed (aggregated ciphertext can be decrypted to the random number). A new round is i + 1.
- Go to step 1.
- Disclaimer
- Implementation details
- Blockchain and Clients
- How to run it locally
- How to run a local testnet with Docker
- How to run a distributed testnet with Digital Ocean
This software is considered experimental. DO NOT USE it for anything security critical at this point.
This is a Proof-of-Concept implementation, so some details from the original paper are simplified here.
Recall, that there are 3 protocol phases (page 12):
- Setup phase. The main purpose of the setup phase is key generating. DKG phase (Section 3.1, page 13) is skipped in this implementation.
dkgcli
simulates DKG-phase and generates private/public keys. These keys have could found in thebots
folder. - Publication phase. Each entropy provider sends ciphertext share and proofs using
hcli tx herb ct-share
command. - Disclosure phase. Each key holder sends decryption share and proof using
hcli tx herb decrypt
command.
Entropy Providers and Key Holders (page 12) are the same sets.
Let's look at the original HERB protocol (page 17) closer.
- Each entropy provider ej, 1 ≤ j ≤ m, generates random point Mj ∈ G. Then encrypts it:
- ej publishes Cj along with NIZK of discrete logarithm knowledge for Aj and NIZK of representation knowledge for Bj
hcli tx herb ct-share [commonPubKey]
command calculates ciphertext share and CE proof and sends a transaction with a Ciphertext Share Message.
- When Cj is published, participants agree that the ciphertext share is correct, if CE-Verify(πCEj,G, Q, Aj, Bj) = 1.
- When all correct Cj are published, participants calculate C = (A, B)
On the blockchain side, keeper's function verifies the ciphertext share and store it into the blockchain. This function also aggregates new ciphertext with cyphertexts which are already stored.
Anyone can see stored ciphertexts by query:
hcli query herb all-ct [round]
Query for aggregated ciphertext:
hcli query herb aggregated-ct [round]
As soon as t1 ciphertext parts were stored, the application's stage changes to "disclosure phase" for the current round.
- Key holder idi, 1 ≤ i ≤ n, publishes decryption shares along with NIZK of discrete logarithm equality
hcli tx herb decrypt [privateKey] [ID]
command queries the aggregated ciphertext and calculates a decryption share. This command also sends a transaction with Decryption Share message.
- When Di is published, participants verify that DLEQ-Verify(πDLEQi,Di,A,VKi,G) = 1
On the blockchain side, keeper's function verifies the decryption share and stores it into the blockchain.
Anyone can see stored decryption shares by query:
hcli query herb all-shares [round]
- When t2 decryption shares published, participants calculate M
As soon as t2 decryption shares were stored, application decrypts an aggregated ciphertext and changes current round stage to "completed". A new round is being started.
Anyone can see generated random number by query:
hcli query herb get-random [round]
HERB round changing depends on transactions by Entropy Providers and Key Holders and doesn't depend on underlying blockchain's height. So one HERB round can take 1 block or 10 blocks, it depends only on HERB participants and blockchain throughput. Anyone can query current round and current stage by commands:
hcli query herb current-round
hcli query herb stage
There are two types of entities who maintain the system:
-
Blockchain full nodes who run application daemon (hd). Let's denote them as nodes.
-
Scripts (HERB) which represents protocol participants. Let's call them clients.
Clients use an application command line interface for querying app state and sending transactions.
-
Install dependencies:
sudo apt-get install expect -y sudo apt-get install make -y sudo apt-get install jq -y
Clone repository to the $HOME directory
Install application:
cd ~/HERB make install
Run setup script:
cd scripts ./init_chain_full.sh t1 t2 n
For example, t1 = t2 = 2, n = 3. n is a total number of clients, t1, t2 is a thresholds (see simplified protocol description).
init_chain.exp
initializes blockchain parameters and creates clients' secret keys (bots folder).Setup blocktime:
cd $HOME/.hd/config sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/' config.toml;
Run application daemon:
hd start
Now node is running and blocks are being generated.
In another terminal run clients:
cd $HOME/HERB ./scripts/run_clients.sh k j
run_clients k j
runs j clients (bot%i%.exp files) starting from k-th client. For instance, for k=0, j=3 it runs 3 client: client0.exp, client1.exp, client2.exp.Random number generation process is started! You can check the current HERB round by query:
hcli query herb current-round
You can get the random number generation results by query:
hcli query herb get-random %round-number%
-
Run the
testnet.sh
script:cd $HOME/HERB ./testnet.sh
Script will display see created docker containers' id.
You can get help:
./testnet.sh -h
If you want to check the random numbers generation process, then connect to the docker container:
sudo docker exec -it %container-id% /bin/bash
Then you can use hcli commands:
hcli query herb current-round hcli query herb get-random %round-number%
To stop the testnet run:
./testnet_stop.sh
For Ubuntu:
-
Create two DigitalOcean ubuntu-droplets (we'll call them node-00 and node-01).
The first one is a "zero"-node, which runs full setup phase. The second one is a "blueprint" which will be duplicated later.
-
Send DigitalOcean associated ssh-keys to node-00:
scp %ssh-keys path% root@%node-00 ip%:.ssh/
-
Run machine_setup.sh script for both nodes. It installs Go and other required software.
cd $HOME/HERB/scripts ssh root@%node-ip% 'bash -s' < machine_setup.sh
Connect to node-00 and perform actions below:
-
Export environment variables:
source ~/.profile
-
Clone repository to the $HOME directory.
git clone https://%username%@github.com/corestario/HERB
-
Install application:
cd ~/HERB make install
Run setup script:
cd $HOME/HERB/scripts ./init_chain_full.sh t1 t1 n
For example, t1 = t2 = 2, n = 3. n is a total number of clients, t1, t2 is a thresholds (see simplified protocol description).
init_chain.exp
initializes blockchain parameters and creates clients' secret keys (bots folder).-
Setup blocktime:
cd $HOME/.hd/config sed -i 's/timeout_commit = "5s"/timeout_commit = "1s"/' config.toml
Send configuration files and keys to node-01:
scp $HOME/.hd/config/genesis.json root@%node-01-ip%: scp -r $HOME/.hcli/keys root@%node-01-ip%: scp $HOME/.hd/config/config.toml root@%node-01-ip%: scp -r $HOME/HERB/bots root@%node-01-ip%:
Run app daemon:
hd start
Connect to node-00 again:
-
Get node-00 tendermint-id:
hcli status
and save "id" value somewhere.
-
Run Prometheus:
cd prometheus-2.11.1.linux-amd64 ./prometheus --config.file=$HOME/HERB/prometheus.yml
Connect to node-00 one more time:
-
Run first clients:
cd $HOME/HERB/scripts ./run_clients.sh 0 %k%
run_clients k j
runs j clients (bot%i%.exp files) starting from k-th client. Other clients will be launched by therun_testnet.sh
script later.Connect to node-01:
-
Export environment variables:
source ~/.profile
-
Clone repository to the $HOME directory
git clone https://%username%@github.com/corestario/HERB
-
Install application:
cd ~/HERB make install
Set node-00 as seed for tendermint:
sed -i 's/seeds = ""/seeds = "%node-00 id%@%node-00 ip%:26656"/' tmp/config.toml
Now, node-01 is our blueprint for other nodes. Make a DigitalOcean snapshot of the node-01.
Create as mush droplets from node-01 snapshot as you need.
Copy IPs all nodes except node-00 to
HERB/scripts/servers.txt
line by line on your machine.Launch all application daemons and clients on the nodes from server.txt file:
cd $HOME/HERB/scripts ./run_distributed_testnet.sh servers.txt %first node number% %client per node%
Here are two arguments:
- first node number - define moniker for node daemon and the number of the first launching client
- client per node - define how many clients (bots files) will be launched on each node
For example: if we run the command with two IPs in the server.txt file:
./run_distributed_testnet.sh servers.txt 1 3
It will launch clients:
client3.exp
,client4.exp
,client5.exp
on the second node;client6.exp
,client7.exp
,client8.exp
on the third node.Now you can check the progress by querying current-round:
hcli query herb current-round
herb's People
Forkers
christiankillerherb's Issues
HERB - DKG vendoring problem
cannot use suite (type "go.dedis.ch/kyber/suites".Suite) as type "github.com/dgamingfoundation/distributed-key-generation/vendor/go.dedis.ch/kyber/suites".Suite in argument to "github.com/dgamingfoundation/distributed-key-generation/dkg".DKG:
"go.dedis.ch/kyber/suites".Suite does not implement "github.com/dgamingfoundation/distributed-key-generation/vendor/go.dedis.ch/kyber/suites".Suite (wrong type for Point method)
have Point() "go.dedis.ch/kyber".Point
want Point() "github.com/dgamingfoundation/distributed-key-generation/vendor/go.dedis.ch/kyber".Pointhttps://www.reddit.com/r/golang/comments/49w33f/how_do_you_handle_vendoring_in_libraries/
https://stackoverflow.com/questions/38091816/packages-type-cannot-be-used-as-the-vendored-packages-typeHandle errors properly
The issue is about fixing
we need to handle this err value somehow
HERB: Incorrect auto gas
Without doubling panic "WritePerByte" occures:
txBldr := auth.NewTxBuilderFromCLI().WithTxEncoder(utils.GetTxEncoder(cdc))
txBldr, err = utils.EnrichWithGas(txBldr, cliCtx, []sdk.Msg{msg})
if err != nil {
return err
}
txBldr = txBldr.WithGas(2 * txBldr.Gas())Use standart key generation function instead of `rand.RandEllipticKey` + scalar multiplication
Core review - second step
Going to add more tests and simplify methods as it's possible.
related to #1
DecShareJSON contains "combined" Value and Identifier
type DecryptionShareJSON struct {
DecShare stringjson:"decryption_share"
DLEproof stringjson:"dle_proof"
KeyHolderAddr sdk.AccAddressjson:"key_holder"
}Rename temporary and not obvious variables
At the moment we have a few variables like
temp
,tempPoint
, most of them can be renamed in a more meaningful way. Seewe need more meaningful names instead of temp, pointTemp1, pointTemp2
Return meaningful zero value or add error value
We should fix
is it a correct return value?
in the code and return either a correct zero value or error as a second return parameter.HERB config optimization
Code review - first step
It's only about obvious errors, golang code style and adding the very first test.
Use go-cmp package instead of `reflect.DeepEqual`
https://github.com/google/go-cmp should help us to remove
reflect
magicPoint-at-infinity doesn't belong to the curve
At the moment golang elliptic package doesn't handle point-at-infinity correctly. It's mentioned in the package comments that 0,0 point should be a point-at-infinity, however, it isn't.
Saparate unit and integration tests
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.