#[cfg(feature = "serde")]
use serde::Serialize;
pub const N: usize = 256;
pub const Q: i64 = 8_380_417;
pub const Q_HALF: i64 = (Q - 1) / 2;
pub const MONT_R: i64 = 4_193_792;
pub const MONT_R_INV: i64 = 8_265_825;
pub const Q_INV: i64 = 58_728_449;
pub const MAX_ATTEMPTS: usize = 256;
pub const OUTPUT_SIZE: usize = 64;
pub const CHALLENGE_SEED_SIZE: usize = 32;
pub const SEED_SIZE: usize = 32;
pub const DOMAIN_CHALLENGE: &[u8] = b"eyvara-challenge";
pub const DOMAIN_OUTPUT: &[u8] = b"eyvara-output";
pub const DOMAIN_MATRIX: &[u8] = b"vrf-matrix\x00\x00\x00\x00\x00\x00";
#[cfg_attr(feature = "serde", derive(Serialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Params {
n: usize,
k: usize,
q: i64,
eta: i64,
gamma_1: i64,
gamma_2: i64,
tau: usize,
beta: i64,
omega: usize,
}
impl Params {
#[allow(clippy::too_many_arguments)]
const fn new(
n: usize,
k: usize,
q: i64,
eta: i64,
gamma_1: i64,
gamma_2: i64,
tau: usize,
beta: i64,
omega: usize,
) -> Self {
assert!(tau <= n, "tau must not exceed n");
assert!(tau > 0, "tau must be positive");
assert!(gamma_1 > beta, "gamma_1 must exceed beta");
assert!(gamma_2 > 0, "gamma_2 must be positive");
assert!(beta > 0, "beta must be positive");
assert!(eta > 0, "eta must be positive");
assert!(omega > 0, "omega must be positive");
assert!(k > 0, "k must be positive");
assert!(q > 0, "q must be positive");
Self {
n,
k,
q,
eta,
gamma_1,
gamma_2,
tau,
beta,
omega,
}
}
pub const fn n(&self) -> usize {
self.n
}
pub const fn k(&self) -> usize {
self.k
}
pub const fn q(&self) -> i64 {
self.q
}
pub const fn eta(&self) -> i64 {
self.eta
}
pub const fn gamma_1(&self) -> i64 {
self.gamma_1
}
pub const fn gamma_2(&self) -> i64 {
self.gamma_2
}
pub const fn tau(&self) -> usize {
self.tau
}
pub const fn beta(&self) -> i64 {
self.beta
}
pub const fn omega(&self) -> usize {
self.omega
}
pub const fn rejection_bound(&self) -> i64 {
self.gamma_1 - self.beta
}
}
pub const EYVARA_128: Params = Params::new(256, 2, 8_380_417, 2, 131_072, 95_232, 39, 78, 80);
pub const EYVARA_192: Params = Params::new(256, 3, 8_380_417, 2, 524_288, 261_888, 49, 98, 120);
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_eyvara_i_rejection_bound() {
assert_eq!(EYVARA_128.rejection_bound(), 131_072 - 78);
}
#[test]
fn test_eyvara_iii_rejection_bound() {
assert_eq!(EYVARA_192.rejection_bound(), 524_288 - 98);
}
#[test]
fn test_gamma2_divides_q_minus_1() {
assert_eq!((Q - 1) % (2 * EYVARA_128.gamma_2()), 0);
assert_eq!((Q - 1) % (2 * EYVARA_192.gamma_2()), 0);
}
#[test]
fn test_domain_tags_are_nonempty() {
assert_eq!(DOMAIN_CHALLENGE.len(), 16);
assert!(!DOMAIN_OUTPUT.is_empty());
assert_eq!(DOMAIN_MATRIX.len(), 16);
}
}