Skip to content

Milestone 3 · Verification

Nuvex maintainers
Aurora over a snow field under a star field

The verifier

VRF is the first job type that needs a proof, and the protocol does not invent one. Verification is the solana-ecvrf crate at version 0.0.1, with the suite named by RFC 9381.

  • Algorithm: ECVRF-EDWARDS25519-SHA512-TAI, RFC 9381, suite byte 0x03.
  • Public key: a 32-byte compressed Ed25519 point.
  • Proof: 80 bytes, laid out as Gamma (32) || c (16) || s (32).
  • Output: the 64-byte beta_string.

On-chain hashing uses the sol_sha512 syscall from SIMD-0512, so a cluster where that feature is inactive cannot run the verifier at all. Host proving comes from the crate's prove feature and is not compiled into the programs.

VerificationRFC 9381
  1. COMMITTEDproof submitted with the output
  2. VERIFIEDECVRF checked by the program
  3. FINALIZED64-byte output written
  4. EXECUTEDcallback ran, no accounts passed
Illustration · not chain data
Illustration · not chain data

Binding the proof to one request

A proof is only meaningful if it is tied to the question that was asked. The alpha string is built by the nuvex-vrf crate from account state and the request's own fields, and is never taken from instruction data.

alpha = "nuvex-vrf-v1"
      || request account pubkey   (32 bytes)
      || job type                 (u8)
      || input length             (u16, little endian)
      || input bytes

Because the request account's address is inside the alpha, a proof produced for one request cannot be replayed into another, and the status leaving Pending stops the same request being fulfilled twice.

Where the result lives

The verification program owns a VrfResult account under the seeds ["verification", request], holding the request, the node, the VRF public key, the output and the proof. Oracle core creates it by CPI and the protocol PDA is the required signer, which is what prevents a user from submitting an alpha that is not bound to a real request. A forged proof is not a protocol result, and the tests keep rejecting one.

ProgramsAnchor 1.2
  • oracle-corerequests, callbacksLive
  • oracle-registrynodes, stake, slashLive
  • verificationECVRF proofsLive
Illustration · not chain data

The missing audit

The crate documents the RFC Appendix B.3 test vectors and its own Mollusk measurements of roughly 10,000 compute units. Measurements are not an audit, and this repository does not present them as one.

“The verifier is solana-ecvrf 0.0.1. No audit report was found. ADR 0004 records that absence.”
Protocol README, Open decisions

Nothing has been audited at the protocol level either. security/AUDIT_SCOPE.md is the scope a future auditor would be asked to cover, and it says plainly that no audit has been commissioned and that the file is not a report.

What a consumer can and cannot rely on

One key has one output for one alpha, and a consumer can build on that uniqueness. The property a consumer does not get is independence from an operator who registered several keys before the request existed, which is the limitation recorded in ADR 0003.

“Rejected: a hand-rolled hash of a node signature presented as a VRF. It is not a VRF.”
ADR 0004: Verification model

Price, data, compute and inference verifiers do not exist. The verification ADR sketches what each would need, and each sketch belongs to a later milestone.

Proving on the host

The Rust SDK can produce a proof locally, which is how the tests exercise the verifier. The secret stays with the caller, and the function returns the public key, the output and the proof together.

use nuvex_job_types::JobType;
use nuvex_sdk::prove_vrf;

let proof = prove_vrf(&secret, &request, JobType::Vrf, &input)?;
assert_eq!(proof.proof.len(), 80);
assert_eq!(proof.output.len(), 64);

Proving is not submitting. The SDKs derive addresses and build bytes, and they still refuse to send a transaction.

A night sky over a mountain ridge
Nuvex maintainersMilestone 5

Protocol

A price median is not a proof

Milestone 5 asks public venues for SOL, BTC, and ETH, drops anything stale or failed, and returns the median only when enough sources remain. The programs still reject a Price request.

Read the post
Earth from orbit beside a spacecraft
Nuvex maintainersMilestone 4

Protocol

The read model copies accounts. It does not decide them

Milestone 4 adds an indexer, a PostgreSQL store, and a read API the console and CLI can query. An empty list is a real answer. A row in that list is still not a finalized result.

Read the post