vrf_fun 0.12.0

RFC 9381 compliant Verifiable Random Function (VRF) for secp256k1
# vrf_fun

Verifiable Random Function (VRF) implementation for secp256k1.

## Use

```toml
[dependencies]
vrf_fun = "0.12"
secp256kfun = "0.12"
sha2 = "0.10"
```

## Overview

This crate provides RFC 9381 compliant VRF implementations for secp256k1, supporting both:
- **TAI (Try-And-Increment)** hash-to-curve method
- **RFC 9380** hash-to-curve method

## Features

- RFC 9381 compliant VRF implementation
- Support for both TAI and RFC 9380 hash-to-curve methods
- Simple VRF variant for when spec compliance is not required
- Generic over hash functions (SHA-256, etc.)
- Deterministic proofs
  - Suite strings: `0xFE` for TAI, `0xFF` for RFC SSWU
  
## Usage

### High-Level API

#### RFC 9381 with TAI (Try-And-Increment)

```rust
use secp256kfun::{prelude::*, KeyPair};
use vrf_fun::rfc9381;

// Generate a keypair
let keypair = KeyPair::new(Scalar::random(&mut rand::thread_rng()));

// Create a VRF proof
let alpha = b"test message";
let proof = rfc9381::tai::prove::<sha2::Sha256>(&keypair, alpha);

// Verify the proof
let verified = rfc9381::tai::verify::<sha2::Sha256>(
    keypair.public_key(), 
    alpha, 
    &proof
).expect("proof should verify");

// Get the VRF output
let beta = verified.rfc9381_output::<sha2::Sha256>();
```

#### RFC 9381 with RFC 9380 Hash-to-Curve

```rust
use vrf_fun::rfc9381;

// Same keypair and message
let proof = rfc9381::sswu::prove::<sha2::Sha256>(&keypair, alpha);

// Verify with the RFC 9380 verifier
let verified = rfc9381::sswu::verify::<sha2::Sha256>(
    keypair.public_key(), 
    alpha, 
    &proof
).expect("proof should verify");

let beta = verified.rfc9381_sswu_output::<sha2::Sha256>();
```

### Low-Level API

For more control over the hash-to-curve process:

```rust
use vrf_fun::{rfc9381::Rfc9381TaiVrf, SimpleVrf};
use secp256kfun::{prelude::*, KeyPair};

// Create VRF instance
let vrf = Rfc9381TaiVrf::<sha2::Sha256>::default();

// Hash to curve yourself
let h = Point::hash_to_curve_rfc9381_tai::<sha2::Sha256>(alpha, b"");

// Generate proof
let proof = vrf.prove(&keypair, h);

// Verify
let verified = vrf.verify(keypair.public_key(), h, &proof)
    .expect("proof should verify");
```

## Implementation Details

### Challenge Generation

The challenge is computed as:
```
c = Hash(suite_string || 0x02 || Y || H || Gamma || U || V || 0x00)
```

Where:
- `suite_string`: `0xFE` for TAI, `0xFF` for RFC 9380
- `Y` is the public key
- `H` is the hash-to-curve of the input
- `Gamma` is the VRF output point (x*H)
- `U` and `V` are the DLEQ proof commitments

The hash output is truncated to 16 bytes for secp256k1.

### VRF Output

The VRF output beta is computed as:
```
beta = Hash(suite_string || 0x03 || Gamma || 0x00)
```

## Important Notes

- The TAI and RFC 9380 variants use different suite strings (0xFE and 0xFF)
- Proofs generated with one method cannot be verified with the other
- The same input will produce different outputs with different hash-to-curve methods
- This implementation includes the public key in the challenge (unlike draft-05)

## Generic Hash Support

The implementation is generic over the hash function, constrained by `secp256kfun::hash::Hash32`. This allows using different SHA256 implementations or other 32-byte output hash functions.