This library lets you use Verifiable Random Functions (VRF) in your web browser. It is based on the libsodium cryptographic library and provides a simple interface for generating VRF proofs and verifying them.
IMPORTANT: This VRF (Verifiable Random Function) library has not been officially audited by security professionals. As such, it should be considered experimental and potentially unreliable. Use this library at your own risk. It is not recommended for use in production environments, especially those handling sensitive data or requiring high security assurances. For critical applications, please seek a professionally audited and well-established cryptographic library.
Initializes the VRF class. This must be called before accessing other functions.
- Returns: Promise
- Async: Yes
- Arguments: None
- Description: Sets up the WebAssembly module and prepares the VRF functions for use.
Generates a new key pair for VRF usage.
- Returns:
{ publicKey: Uint8Array, secretKey: Uint8Array, result: number }
- Async: No
- Arguments: None
- Description: Creates a new key pair specifically for VRF. It's recommended to use this function rather than other key generation methods for VRF operations.
Generates a VRF proof based on a secret key and a message.
- Returns:
{ proof: Uint8Array, result: number }
- Async: No
- Arguments:
sk
(Uint8Array): Secret VRF keymessage
(Uint8Array): VRF proof seed
- Description: Produces a VRF proof using the provided secret key and message (seed).
Verifies a VRF proof and returns its corresponding output.
- Returns:
{ output: Uint8Array, result: number }
- Async: No
- Arguments:
pk
(Uint8Array): Public VRF keyproof
(Uint8Array): VRF proofmessage
(Uint8Array): Seed used for VRF proof generation
- Description: Checks the validity of a VRF proof and returns the verified output if successful.
Converts a VRF proof to its corresponding hash without verification.
- Returns:
{ hash: Uint8Array, result: number }
- Async: No
- Arguments:
proof
(Uint8Array): VRF proof
- Description: Generates the hash of a given proof without performing verification.
- All functions (except
init()
) return an object that includes aresult
property. Thisresult
is typically a number where:0
indicates success- Non-zero values indicate various types of failures (refer to the libsodium documentation for specific error codes)
- It's recommended to always check the
result
value to ensure the operation was successful before using the returned data.
async function runVRF() {
await VRF.init();
const { publicKey, secretKey, result: keyGenResult } = VRF.keypair();
if (keyGenResult !== 0) {
console.error("Key generation failed");
return;
}
const message = new TextEncoder().encode("Hello, VRF!");
const { proof, result: proofResult } = VRF.prove(secretKey, message);
if (proofResult !== 0) {
console.error("Proof generation failed");
return;
}
const { output, result: verifyResult } = VRF.verify(
publicKey,
proof,
message
);
if (verifyResult !== 0) {
console.error("Proof verification failed");
return;
}
console.log("VRF Output:", output);
}
runVRF().catch(console.error);
This library provides a robust implementation of VRF functions, suitable for various cryptographic applications requiring verifiable randomness.
Below instructions worked on Ubuntu 24.04 LTS.
This software allows translation of C code to WebAssembly. Installation instructions are below and were copier from emscripten.org.
git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
cd ..
This is a fork of sodium native made by Applied Blockchain that adds necessary VRF functions
npm pack @appliedblockchain/sodium-native
tar -xvf appliedblockchain-sodium-native-3.3.2.tgz
cd package
This install necessary NPM dependencies & fetches Algorand libsodium from Applied Blockchain libsodium fork
May take a long time
yarn && yarn fetch-libsodium
This makes libsodium from source
May take a long time
cd deps/libsodium-1.0.16-algorand/
emconfigure ./configure --disable-shared --prefix="$PWD/libsodium-wasm"
emmake make
emmake make install
cd ../../
cp ../vrf_wrapper.c .
emcc -O3 vrf_wrapper.c -I./deps/libsodium-1.0.16-algorand/src/libsodium/include -L./deps/libsodium-1.0.16-algorand/src/libsodium/.libs -lsodium -s WASM=1 -s EXPORTED_FUNCTIONS="['_malloc', '_free', '_vrf_publickeybytes', '_vrf_secretkeybytes', '_vrf_proofbytes', '_vrf_outputbytes']" -s EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s ENVIRONMENT='web' -s INCOMING_MODULE_JS_API="['onRuntimeInitialized']" -sSINGLE_FILE -o vrf.js
This should create vrf.js output file in package directory.
You need to replace const vrf_js_base64 = "..."
in index.js with the base64-encoded content of vrf.js.
You can generate it with this command:
base64 vrf.js | tr -d '\n'
Congrats, now you can use VRF in your web browser. To check, you can launch the index.html file.
python3 -m http.server
Then click on your localhost link (most likely 0.0.0.0:8000). You can inspect the correctness of the library using the developer console (F12).
It should look something like this:
(index):41 Public Key: Uint8Array(32)
(index):42 Secret Key: Uint8Array(64)
(index):46 Proof: Uint8Array(80)
(index):49 Verification result: Success
(index):50 Output: Uint8Array(64)
(index):53 Hash: Uint8Array(64)