ADR-002 — VRF Implementation: HMAC-based vs @noble/curves
Status: PROPOSED
Date: 2026-04-07
Domain: Legitimacy (π Governance, θ Consensus, arbitration)
Context
Verifiable Random Functions (VRFs) are used in three places in Colibri’s legitimacy layer:
- Entropy injection (π Governance, P6.2): VRF selects 10% of voters for equal-weight ballots on proposals with >5% numeric delta.
- Arbiter selection (θ Consensus / arbitration): VRF selects arbiters for dispute resolution (S09,
EVT-B02 ArbitersAssigned). - Leader election (θ Consensus): VRF elects a BFT round leader per epoch.
A VRF must satisfy three properties:
- Verifiable: anyone can confirm the output is correct given the proof
- Deterministic: same input always produces the same output
- Unpredictable: output cannot be predicted before the VRF seed is revealed
Reference algorithm: VRF specification documented in extraction files.
The reference implementation used HMAC-SHA256 as a simplified stand-in for the full ECVRF-EDWARDS25519-SHA512-TAI construction from RFC 9381.
Reference: See pseudocode in docs/reference/extractions/ for algorithm details.
Decision
TBD — requires PM decision.
This ADR documents the two viable approaches. The PM should consider whether strict RFC 9381 compliance is required for external interoperability, or whether a simpler HMAC-based approach is sufficient for Colibri’s internal use.
Options
Option A: HMAC-SHA256 internal implementation (port the Python approach)
Implement a HMAC-SHA256 VRF using node:crypto (built-in). This is a simplified VRF approach (not full EC-VRF per RFC 9381).
Target file: src/rules/vrf.js (Phase 1+)
Pros:
- Zero new dependencies — uses only
node:crypto(built-in) - Sufficient for Colibri’s internal use (governance, arbitration, leader election are internal consensus mechanisms, not externally-verifiable proofs)
- Fast: HMAC-SHA256 is a single call
Cons:
- Not a compliant RFC 9381 ECVRF — cannot interoperate with external VRF verifiers
- A production-grade system should use proper EC-VRF for external verifiability
- If Colibri later exposes VRF proofs to external observers, the proofs would not be verifiable by standard tools
Option B: @noble/curves (Ed25519 EC-VRF per RFC 9381)
Use the @noble/curves library (@noble/curves/ed25519) which provides audited, pure-JavaScript Ed25519 operations. Implement the RFC 9381 ECVRF-EDWARDS25519-SHA512-TAI construction on top.
Target file: src/rules/vrf.js (Phase 1+)
Pros:
- RFC 9381 compliant — VRF proofs verifiable by external tools
@noble/curvesis widely used, audited, pure JS (no native addon)- Future-proof: if Colibri P2P layer ever exposes proofs publicly, they are standard
- Ed25519 is consistent with Colibri identity system
Cons:
- Adds a new npm dependency to audit and maintain
- Implementing RFC 9381 correctly is non-trivial (~200 lines)
- Overkill if VRF proofs are never exposed externally
Consequences
If Option A (HMAC, port Python):
- 1-day implementation: direct port of
vrf.py - Governance entropy injection and arbiter selection work immediately
- Technical debt: comment in code must warn that this is not RFC 9381 compliant
- Risk: if external verifiability is ever needed, full rewrite required
If Option B (@noble/curves):
- 3-5 day implementation: RFC 9381 has specific hash-to-curve, nonce generation, and serialization requirements
- VRF proofs are externally verifiable from day one
@noble/curvesis a peer dependency of@noble/hashes(likely already in the tree via other deps)
Alternatives Considered
libsodium.js(wasm): provides Ed25519 but not ECVRF directly; would still need RFC 9381 layer on top@peculiar/webcrypto: WebCrypto polyfill; supports Ed25519 signing but not VRF prove/verify- Build custom native addon with libsodium C: too heavy; native addon for a utility function is not warranted
References
- Reference algorithm in docs/reference/extractions/
- RFC 9381: Verifiable Random Functions (VRFs) — https://www.rfc-editor.org/rfc/rfc9381
@noble/curves— https://github.com/paulmillr/noble-curves- S09 — Arbitration — arbiter selection uses VRF
- S18 — Governance Protocol §2.4 — entropy injection uses VRF
- ADR-003 — BFT library decision (VRF for leader election)