PoA 2.0: VeChain’s Verifiable Random Function Library in Golang
Welcome to another episode of the blockchain-related technical articles!
As you have learned from the official developer-related Twitter account @vechaindev announcement, the core developers have implemented a Verifiable Random Function (VRF) library in Golang as part of the VeChain PoA 2.0 milestone.
Sitting at the core of the “Committee based PoA” algorithm which will bring VeChain to the next level, VRF plays an important role in selecting the members of the committee each round and prevent collaborated fraud in the consensus process.
So what is VRF? Why is it important? Let’s start to explore!
Before You Start
Currently, if you search “Verifiable Random Function” on Github.com, about 20 repositories will pop up. Half of them are written according to the specification of VRF draft v5 between 2018–2019.
VeChain’s implementation is according to the newest draft v6. I include the interesting links below:
- VRF Specification draft 06
- VRF Golang library on Github
- VIP-193 “Committee based PoA” proposal PDF.
What is VRF?
Verifiable Random Function is the public-key version of a keyed cryptographic hash. The holder of a private key can calculate the hash of a message, and the holders of the public key can verify the hashed message matches the original message and is computed by the private key holder.
Some comparison of the hash functions:
- Unkeyed Hash Function: The hash is computed from the message directly. MD5/SHA256 for example.
- Keyed Hash Function: A secret key is used, together with the message as inputs to be fed into the hash function. The sender and the receiver share the same secret key beforehand. HMAC for example.
- VRF: Use a pair of public/private keys instead of sharing a common secret key.
The process of VRF can be described as the following process:
- The sender computes a hash
betawith original message
alphaand his own secret key
beta = VRF_hash(SK, alpha)
- The sender computes a proof
piwith original message
alphaand his own secret key
pi = VRF_proof(SK, alpha)
- The receiver can verify the message and authenticity of the sender by verifying process:
beta' = VRF_verify(PK, alpha, pi)
beta'matches, then the message is trustworthy.
As we can observe from the process, the sender and receiver rely on a pair of public/private keys. And hence this VRF function can come in various flavors, for example, RSA and Elliptic Curve.
I highly encourage you to read the draft yourself: [Link]
Where is VRF used in PoA 2.0?
As per document VIP-193 (Dr. Zhou, Dr. Ren) suggested, each block producing round, a group of nodes is selected into committee. How to determine the membership of a single node? This process can be fast and swift with VRF function.
This message to be hashed can be a well-known value that changes each round, to mitigate the possibility to be known before the round takes place. And the instant the hash is computed locally, if it is lower than a certain threshold, the node can know he is in the current round committee.
The other nodes can verify the membership of any node by performing a VRF verify operation.
With VRF function, the membership selection is just like a “Lotto” draw result, with a benefit that it can be computed locally!
While the first popular VRF implementation is from Witnet in Rust and Solidity, VeChain developers want to contribute to the coding world with their own implementation in Golang.
The library is fully tested with the specification examples and with Rust generated examples. Currently, it adopts the Elliptic Curve as core trap door function and offers two flavors:
Feel free to fork the project and add your own implementation with other ciphers! [Project URL]