Implemented profile

crypto implements ECVRF-EDWARDS25519-SHA512-TAI (suite 0x03) from RFC 9381, using pinned vrf-rfc9381 = 0.0.7 over the existing Dalek arithmetic. The provider uses the same explicitly registered Ed25519 public keys and BLAKE2s validator identities as signature verification. Unknown identities, weak/noncanonical keys, malformed proofs and incorrect claimed outputs are rejected. This is an implemented and tested provider, not a claim of an independent cryptographic audit.

The backend's scalar decoder reduces values modulo the group order. The wrapper requires proof decode/re-encode equality, rejecting alternative s + q encodings and noncanonical curve points before cryptographic verification. The proof must be exactly 80 bytes. The 64-byte verified RFC output is converted to Hash256 with domain_hash("astrolune.vrf.output.v1", beta); it is never trusted directly from the sender or derived from an ordinary Ed25519 signature.

Context and envelope

VrfInput::seed() hashes these fixed-width fields, in order:

FieldEncoding
chain IDu32 little endian
genesis commitment32 bytes
epochu64 little endian
target heightu64 little endian
finalized parent randomness32 bytes
roundu32 little endian

Committee and producer evaluations use astrolune.vrf.committee.v1 and astrolune.vrf.producer.v1, respectively. The resulting digest is the RFC alpha input. Committee rounds must be zero in the sampler and CLI. Callers obtain the context from trusted finalized state, not from a proof's claims.

The fixed 120-byte output envelope is ALVR || u32_le(1) || randomness[32] || proof[80]. Wrong versions, truncations and trailing bytes are rejected. Structural decoding does not establish authenticity; verification is required.

Weighted draws and rotation

VerifiedVrfSampler requires a complete bounded roster of eligible keys and positive finalized weights, plus exactly one valid proof per roster member. Candidate weights must match the trusted roster. Duplicates, unknown identities, missing contributions and aggregate u128 overflow are errors. Banned and unadmitted validators are excluded when the caller constructs the trusted roster.

The batch commits the context digest and the ordered (identity, weight, randomness) tuples, sorted by identity. A separate hash domain derives a 128-bit ticket for each seat. Rejection sampling discards values below 2^128 mod total_weight before reduction modulo the remaining total. This avoids modulo bias. The rejection loop is capped at 256 attempts and fails without choosing a fallback winner. Cumulative weight intervals select a member with probability weight / remaining_weight, then remove that member. No floating point or arrival order affects the result.

rotate retains the newest size - replacement_count seats, updates their weights from the trusted roster, and samples the other seats without duplicating retained members. Outgoing members may be selected again. Zero replacements preserve seat identities; excessive counts, invalid retained membership and nonconsecutive heights fail. producer requires a separate producer-role batch whose membership and weights exactly equal the active committee. The new producer_for_subset API instead retains full-roster entropy while drawing only among an authenticated selected subset.

The old unverified sorter is now explicitly called DemonstrationSampler. Its replacement-count bug is corrected; it remains a fixture helper.

Operator commands

cli vrf-prove genesis.bin validator.seed 1 5 <parent-randomness-hex> committee 0 proof.bin
cli vrf-verify genesis.bin <public-key-hex> 1 5 <parent-randomness-hex> committee 0 proof.bin

The CLI verifies genesis membership, reads exactly 32 secret bytes from a file, never prints secrets, and creates proof files exclusively without overwriting. Changing the context, key, proof or claimed randomness causes verification to fail. This CLI uses the genesis roster; it does not infer later membership changes.

Activation boundary

The certified daemon retains fixed membership for version-1 genesis. Explicit version-2 activation enables contribution gossip, complete-roster availability, standby participation, historical handoff RPC and client catch-up. The handoff and rotating execution APIs implement parent randomness, old-quorum trust transfer, reserved system execution and authenticated history replay. Existing network identities are never migrated implicitly; activation requires a new trusted genesis and signing namespace.

The complete roster must be fixed before proof revelation. Missing proofs halt this sampler; dropping missing validators or changing the seed would create a different lottery and is not an automatic fallback. Withholding resistance, grinding analysis and rotating-committee liveness are separate unresolved tasks.

Tests cover RFC examples 16–18, every proof-byte mutation, output mutation, wrong contexts/keys, scalar malleability, envelope bounds, trusted weights, canonical batch ordering, rotation, producer membership and finality-context construction. Integer draw tests exercise full-width totals and weighted intervals.

Источник: docs/28-vrf-and-weighted-selection.md
Отдельная MDX-копия · SHA-256 исходника: dfbb37709a93d1fe157ee596196d0483734d6fbaaee5dd8b5951bc5897022d20