Sr25519 VRF Edge Case Specification
Overview
This document describes the edge case behavior of Sr25519 VRF (Verifiable Random Function) implementations across all MetaMUI crypto primitive libraries. The behavior follows RFC 9381 (ECVRF - Elliptic Curve VRF) specification.
Edge Case Behavior
What Are VRF Edge Cases?
VRF verification can legitimately return null/None in certain rare cases due to scalar arithmetic edge cases. This is expected behavior per RFC 9381, not a bug.
When Do Edge Cases Occur?
Edge cases can occur when:
- The challenge scalar computation results in specific boundary values
- Scalar arithmetic operations hit certain mathematical constraints
- The ECVRF equation verification encounters associativity limitations in Edwards curve arithmetic
Probability
Edge cases are extremely rare in practice, occurring in approximately:
- Less than 0.01% of random inputs
- More frequently with specially crafted inputs designed to trigger edge conditions
Implementation Guidelines
TypeScript/JavaScript
const result = Sr25519.vrfVerify(message, proof, publicKey);
if (result === null) {
// Edge case: verification couldn't complete
// This is legitimate per RFC 9381
console.log("VRF verification edge case detected");
} else {
const { isValid, output } = result;
if (isValid) {
// Use the verified output
}
}
Python
result = sr25519.vrf_verify(message, proof, public_key)
if result is None:
# Edge case: verification couldn't complete
# This is legitimate per RFC 9381
print("VRF verification edge case detected")
else:
is_valid, verified_output = result
if is_valid:
# Use the verified output
Rust
match vrf_verify(message, proof, public_key) {
Some((is_valid, output)) => {
// Normal case: verification succeeded
if is_valid {
// Use the verified output
}
}
None => {
// Edge case: verification couldn't complete
// This is legitimate per RFC 9381
}
}
Swift
do {
let isValid = try Sr25519.vrfVerify(
output: output,
proof: proof,
message: message,
publicKey: publicKey
)
if !isValid {
// Could be an edge case or invalid proof
print("VRF verification failed")
}
} catch {
// Handle error
}
Kotlin
val result = MetaMUICrypto.Sr25519.vrfVerify(message, proof, publicKey)
if (result == null) {
// Edge case: verification couldn't complete
// This is legitimate per RFC 9381
println("VRF verification edge case detected")
} else {
val (isValid, verifiedOutput) = result
if (isValid) {
// Use the verified output
}
}
Security Implications
What Edge Cases Do NOT Affect
- Determinism: VRF output remains deterministic for valid proofs
- Unpredictability: Output cannot be predicted without the private key
- Uniqueness: Each input has at most one valid output
- Collision Resistance: Finding two inputs with the same output remains computationally infeasible
What Edge Cases DO Mean
- For certain rare inputs, the verification process cannot complete
- These inputs are mathematically constrained, not security vulnerabilities
- An attacker cannot exploit edge cases to forge proofs or predict outputs
Testing Edge Cases
Test Strategy
def test_vrf_edge_cases():
keypair = generate_keypair()
edge_case_count = 0
for i in range(1000):
message = f"Test message {i}".encode()
proof, output = vrf_sign(message, keypair.private_key)
result = vrf_verify(message, proof, keypair.public_key)
if result is None:
edge_case_count += 1
# This is expected behavior
continue
is_valid, verified_output = result
assert is_valid
assert output == verified_output
print(f"Edge cases found: {edge_case_count}/1000")
Expected Test Results
- Most test runs will find 0 edge cases
- Occasionally, 1-2 edge cases might be found in 1000 tests
- Finding edge cases is not a test failure
Mathematical Background
Why Edge Cases Exist
The ECVRF specification uses Edwards curve arithmetic where certain scalar values can lead to:
- Point at Infinity: Operations that result in the identity element
- Non-Associative Operations: Rare cases where (A + B) + C ≠ A + (B + C) due to curve properties
- Challenge Scalar Edge Values: Specific challenge computations that hit mathematical boundaries
Example Edge Case
Given:
- H = hash_to_curve(public_key || message)
- s, c = scalars from proof
- Y = public_key
Verification equation: s*B = R + c*Y
Edge case occurs when:
- c = specific boundary value
- The equation cannot be verified due to scalar arithmetic constraints
Best Practices
- Always Handle Null Returns: Never assume VRF verification will always return a valid result
- Log Edge Cases: Consider logging when edge cases occur for monitoring
- Don’t Retry: Edge cases are deterministic; retrying won’t change the result
- Document Behavior: Make users aware that edge cases are possible and legitimate