An analysis of Supra's "decentralized VRF" implementation. The conclusion: under the actual trust model, it fails to provide not just the "d" (decentralized), but also the "V" (verifiable) and "R" (random) properties that define a VRF.
From Supra's website:
Supra's decentralized Verifiable Random Function (dVRF) provides a secure, tamper-proof solution for generating random numbers in Web3 applications. Unlike centralized VRF systems that create single points of failure, dVRF distributes trust across multiple nodes while maintaining cryptographic verifiability.
Centralized VRF computation introduces its own problem by relying on a single node to store the private key. This creates a single point of failure and is inherently incompatible with decentralization principles. The centralized approach requires complete trust in one entity, which contradicts the fundamental values of blockchain technology.
Supra's approach uses the GLOW construction developed by Galindo et al., which builds heavily on BLS threshold signatures. BLS threshold signatures enable signature generation by any T+1 nodes, naturally ensuring the consistency property required for dVRF.
The application receives both the VRF output and the BLS signature as proof. Verification involves checking that the proof is a valid BLS signature and that the VRF output equals the hash of that signature. This verification process is identical to centralized VRF verification, enabling seamless integration.
The VRF Service Whitepaper is available at: https://supra.com/documents/VRF-Service-Whitepaper.pdf
The "Verifiable" in VRF refers to verifying that an output was correctly computed from a given input and public key. It does not verify that the key was generated in a distributed manner, or that a threshold committee exists and is operating as claimed.
From an external observer's perspective, Supra's dVRF is indistinguishable from a centralized VRF.
- The BLS signature is valid against the published public key
- The VRF output is the hash of that signature
- That the public key was generated via a proper Distributed Key Generation (DKG) ceremony
- The threshold parameter
t(how many nodes must collude to predict outputs) - The total number of nodes
nin the committee - The identities or independence of committee members
- That the aggregator isn't colluding or operating as a single signer
- That key rotations follow any distributed process
The problems go deeper than unverifiable decentralization. Under the actual trust model, the core VRF properties themselves—Verifiable and Random—collapse entirely.
VRF verification proves that an output was correctly computed for a given public key. But when the admin can rotate the public key at will via updatePublicKey, verification becomes tautological.
Attack scenario:
- Admin observes a VRF request (the input is public)
- Admin wants output to fall in a specific range (e.g., to rig a lottery)
- Admin generates keypairs until finding one where
H(BLS.sign(sk, input))produces desired output - Admin calls
updatePublicKey(pk)with the new key - Admin submits the signature
- Verification passes—the signature is valid for the current public key
The user is verifying against a target the adversary controls. This is like a casino "proving" dice rolls are fair by showing the dice match the outcome they announced—after they rolled.
For verification to be meaningful, the public key must be committed before the input is known. The contract includes a block hash in the input:
// Input includes: _clientSeed, block.chainid, _requestBlockNumberBut the admin sees the finalized block (including its hash) before they sign and submit. There's no commit-reveal scheme that binds the key to a point before the input is determined.
BLS signatures are deterministic functions of the secret key and message:
There is no randomness in the signing process. The "random" output is:
This is a deterministic function. From the admin's perspective (knowing sk), every output is fully predictable before any request is made.
The "randomness" in a VRF comes from the unpredictability of the output to parties who don't know sk. This requires:
-
Threshold assumption: No single party knows
sk—only shares$sk_i$ exist - This assumption is unverifiable in Supra's implementation
If the admin controls the full secret key (which is indistinguishable from threshold operation on-chain), they can compute:
for all possible future inputs:
output[input] = H(BLS.sign(sk, input))There is no randomness. It's a lookup table the admin has already computed.
Stripping away the terminology, Supra's system is:
| Property | VRF Requirement | Supra Reality |
|---|---|---|
| Random | Output unpredictable to all parties | Fully predictable to admin |
| Verifiable | Anyone can check correctness | Checking against admin-controlled key |
| Function | Deterministic for given key | Yes (this part works) |
It's a Deterministic Function with an admin-controlled key—a DF, not a VRF. The "V" and "R" require trust assumptions that aren't enforced anywhere on-chain.
A more honest description would be: "Supra's Administered Deterministic Function (ADF) provides outputs that users can verify were signed by Supra's current key."
The whitepaper itself reveals the trust gap:
From Section 4 (page 8):
"We do not provide specific details of the distributed key-generation (DKG) procedure here, instead we just mention the input and output."
The DKG produces a public key
From Section 3 (page 5):
"We assume that at most f ≤ t parties can be maliciously corrupt."
And:
"We always assume f = t < ⌈n/2⌉ – this restriction is required for the liveness/availability."
These parameters (n, t, f) are never published or committed to on-chain. External observers have no way to verify these assumptions hold.
The GLOW construction produces individual verification keys pk reaches the chain.
From Section 6 (page 14):
"The relay nodes fetch the input, verify legitimacy of INP (for example, by verifying the signature provided by the contract), whether it was previously used, and if all checks are satisfactory, forwards INP to all nodes within the VRF clan."
The aggregator collects partial evaluations and produces the final signature. This is entirely off-chain and unauditable.
From Section 3 (page 4):
"However, from their description [Cha] it seems that their VRF secret-key is not decentralized (in other words, they do not use a DVRF), and therefore, their scheme is susceptible to a single point of failure. This means that if a specific node is compromised, the entire secret-key is known to the attacker."
Yet Supra's deployment is indistinguishable from this to external observers. The cryptographic machinery for threshold signatures exists, but there's no way to verify it's actually being used.
- SupraRouterContract: 0x7d86fbfc0701d0bf273fd550eb65be1002ed304e
- SupraGeneratorContract: 0x095d165ad8651ec48ec9dd9d4c749f9f071963d0
Note: The Router contract doesn't expose the Generator contract's address (_supraGeneratorContract is internal). This address was identified by monitoring admin contract calls.
1. Client requests randomness via Router
// SupraRouterContract.sol:324
function generateRequest(string memory _functionSig, uint8 _rngCount, ...) {
// Forwards to generator contract
_supraGeneratorContract.call(abi.encodeWithSignature(
'rngRequest(uint256,string,uint8,address,uint256,uint256,address)', ...
));
}2. Generator emits event, off-chain "free nodes" observe it
// SupraGeneratorContract.sol:482
emit RequestGenerated(_nonce, instanceId, _callerContract, ...);3. A whitelisted "free node" submits the callback with a BLS signature
// SupraGeneratorContract.sol:199
function generateRngCallback(
uint256 _nonce,
uint256[2] calldata _signature, // BLS signature
...
) public nonReentrant {
if(!isFreeNodeWhitelisted(msg.sender)) {
revert FreeNodeNotWhitelisted();
}
// ...
}4. The signature is verified against a stored public key
// SupraGeneratorContract.sol:600
function verify(bytes32 _message, uint256[2] calldata _signature) internal view {
(checkSuccess, callSuccess) = BLS.verifySingle(
_signature,
publicKey, // uint256[4] - a single BLS G2 point
BLS.hashToPoint(domain, abi.encode(_message)),
blsPreCompileGasCost
);
}5. Random numbers are derived from the signature and sent to Router
// SupraGeneratorContract.sol:417-419
for (uint256 loop = 0; loop < _rngCount; ++loop) {
rngList[loop] = uint256(keccak256(abi.encodePacked(_signature, loop + 1)));
}
// Then calls supraRouterContract.rngCallback(...)6. Router invokes the client's callback
// SupraRouterContract.sol:356
function rngCallback(uint256 nonce, uint256[] memory rngList, address _clientContractAddress, string memory _functionSig) {
if (msg.sender != _supraGeneratorContract) revert OwnerOnly();
_clientContractAddress.call(abi.encodeWithSignature(_functionSig, nonce, rngList));
}The public key is a single point, not a set of verification keys:
// SupraGeneratorContract.sol:29
uint256[4] public publicKey; // Single BLS12-381 G2 pointThere is no storage for:
- Individual verification keys
$vk_i = {G_1}^{s_i}$ for committee members - Threshold parameter
t - Number of nodes
n - Committee member identities
The updatePublicKey function has no DKG verification:
// SupraGeneratorContract.sol:575-583
function updatePublicKey(uint256[4] memory _publicKey)
external
onlyOwner
returns (bool)
{
publicKey = _publicKey;
emit PublicKeyUpdated(block.timestamp);
return true;
}This is a simple assignment guarded only by onlyOwner. There is:
- No proof that the new key came from a DKG ceremony
- No commitment to committee membership
- No multi-sig requirement
- No timelock or governance process
"Free nodes" are not the threshold signers:
The whitelistedFreeNodes (line 56) are addresses permitted to submit callbacks—they are the relay/aggregator layer, not the VRF committee itself. The actual signing happens entirely off-chain.
A single entity with access to the owner key could:
- Generate a standard (non-threshold) BLS keypair:
sk, pk = BLS.keygen() - Call
updatePublicKey(pk) - Sign all VRF requests themselves:
sig = BLS.sign(sk, message) - Submit via any whitelisted free node
This would be completely undetectable to users of the service. The on-chain verification would pass, and there's no way to distinguish this from legitimate threshold operation.
For the "d" in dVRF to be meaningful, Supra would need to provide:
-
On-chain DKG commitments: Publish all individual verification keys
$vk_i$ during key generation -
Published threshold parameters: Commit to
n(total nodes) andt(threshold) on-chain - Committee transparency: Publish the identities or at minimum pseudonymous identifiers of committee members
-
Verifiable key rotation: Key updates should require on-chain proof of a new DKG ceremony, not a single
updatePublicKeycall -
Partial signature transparency: Optionally publish individual partial signatures
$(y_i, π_i)$ before aggregation, allowing verification that multiple parties participated
Without these, the security guarantee reduces to: "Trust Supra's operational claims."
The GLOW construction is cryptographically sound and was published at IEEE EuroS&P 2021. The mathematics of threshold BLS signatures genuinely provide the security properties Supra claims—if implemented correctly with independent parties and proper transparency.
However, Supra's deployment architecture doesn't just make decentralization unverifiable—it collapses the VRF properties entirely:
| Property | Status | Reason |
|---|---|---|
| Decentralized | Unverifiable | No on-chain DKG proof, committee info, or threshold parameters |
| Verifiable | Meaningless | Verification is against an admin-controlled key that can rotate |
| Random | Nonexistent | Outputs are deterministic and fully predictable to the key holder |
From the admin's perspective, the system is equivalent to:
def supra_vrf(input):
return sha256(bls_sign(ADMIN_SECRET_KEY, input))A deterministic function they fully control, wrapped in threshold cryptography terminology.
This directly contradicts Supra's own criticism of centralized VRF systems:
"The centralized approach requires complete trust in one entity, which contradicts the fundamental values of blockchain technology."
Supra's implementation requires exactly this: complete trust that they're operating a threshold committee, not predicting outputs, and not rotating keys adversarially. None of these can be verified on-chain.
What users are paying for: a deterministic function controlled by Supra, with a smart contract that checks Supra's signatures are valid against Supra's current public key.
What users think they're getting: unpredictable, unbiasable randomness secured by distributed cryptography.
- Galindo, D., Liu, J., Ordean, M., & Wong, J. M. (2021). Fully distributed verifiable random functions and their application to decentralised random beacons. IEEE European Symposium on Security and Privacy (EuroS&P), 88-102. https://eprint.iacr.org/2020/096.pdf
- Supra VRF Service Whitepaper: https://supra.com/documents/VRF-Service-Whitepaper.pdf