A [Verifiable Random Function](https://people.csail.mit.edu/silvio/Selected%20Scientific%20Papers/Pseudo%20Randomness/Verifiable_Random_Functions.pdf) (VRF) is a pseudorandom function that provides proofs that its outputs were constructed in a verifiable manner. While the proof is constructed with both public and private data, i.e., private key, the verification only requires the public data. Not surprisingly, VRFs play an important role in trustless systems, such as blockchain protocols and, of course, the Fluence network. We are implementing [ECVRF](https://github.com/Silur/ECVRF), which uses ED25519, as a Marine Wasm off-chain service callable from Aqua.
* **the [ECVRF](https://github.com/Silur/ECVRF) crate is provided under a GPL-3.0 [License](./LICENSE). Hence, this repo is also made available under a GPL-3.0 license.**
* **neither the [ECVRF](https://github.com/Silur/ECVRF) crate nor this repo have not undergone a security audit. Tread With Care!**
Implementing a Wasm wrapper around the ECVRF library is pretty straight forward. Aside from the proof generation and verification functions, we added a few convenience features you should only use in the intended context of experimentation. The complete code is in the [src/main.rs](./src/main.rs) file.
Compile with:
```bash
./scripts/build.sh
```
And test with:
```bash
cargo +nightly test --release
```
Which should result in:
```bash
running 4 tests
test tests::t_key_gen ... ok
test tests::test_proof_module ... ok
test tests::verify_proof_module_no_sk ... ok
test tests::verify_proof_module_with_sk ... ok
test result: ok. 4 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.19s
```
## Service Deployment
While the Wasm module handles both proof generation and verification, it seems prudent to deploy the service to different peers to separate the proof generation from the verification process.
See [run_data.json](./data/run_data.json) for a sample file populated with the different argument settings for running the [Aqua functions](./aqua/vrf.aqua).
## VRF With Aqua
Let's have a look at our Aqua functions for both creating and verifying a proof:
We can know utilize these parameters to verify the (pseudo) randomness of the result using the prepared [proof_data.json](./data/proof_data.json) file with the above results parameters:
If you change any of the verification parameters, such as the input parameter, the verification fails. For example, change `"payload_arg": [222, 173, 190, 239]` to `"bad_payload_arg": [222, 173, 190, 240]`:
In addition to the core `proof` and `verify` functions, a `vrf_rountrip` function for a test run is available. Moreover, we also provide a (ed25519) key generation function for convenience purposes. In general, **you should not rely on a (untrusted) peer to generate or otherwise handle your secret key** and instead use some client side tool, e.g., openssl, to create and manage your ED25519 keypair(s). Moreover, since the private key is required to create the VRF (and proof), even with a trusted peer, it might be best to work with [ephemeral](https://en.wikipedia.org/wiki/Ephemeral_key) key pairs.
We provide a Marine Wasm wrapper and corresponding Aqua implementation around the *ECVRF* ED25519 Rust project. As a low-cost, off-chain source of pseudorandomness, Fluence users, and especially Marine Wasm developers, do not need to rely on (trustless) peers to provide randomness. Moreover, developers may anchor the provided randomness and proof on-chain for immutable references and off-chain, or even on-chain, verification. In the case of Fluence WASM, it may make sense to use VRF to provable pseudorandom generate seeds for PRNG initiations.