vrf_rfc9381/ec/
util.rs

1#![allow(dead_code)]
2
3use crate::{
4    Ciphersuite,
5    consts::ecvrf::{
6        challenge::{ECVRF_CHAL_GEN_DST_BACK, ECVRF_CHAL_GEN_DST_FRONT},
7        e2c::{ECVRF_E2C_DST_BACK, ECVRF_E2C_DST_FRONT},
8        proof::{ECVRF_PROOF_DST_BACK, ECVRF_PROOF_DST_FRONT},
9    },
10};
11
12pub(crate) fn encode_to_curve_tai_generator<H: digest::Digest>(
13    suite: Ciphersuite,
14    salt: &[u8],
15    alpha: &[u8],
16) -> impl Iterator<Item = digest::Output<H>> {
17    // 1. ctr = 0
18    let mut ctr = 0u8;
19    std::iter::from_fn(move || {
20        let next_ctr_value = ctr.checked_add(1)?;
21        // hash_string = Hash(
22        //   suite_string || encode_to_curve_domain_separator_front ||
23        //   encode_to_curve_salt || alpha_string ||
24        //   ctr_string || encode_to_curve_domain_separator_back
25        // )
26        let hash_string = H::new()
27            .chain_update([*suite, ECVRF_E2C_DST_FRONT])
28            .chain_update(salt)
29            .chain_update(alpha)
30            .chain_update([ctr, ECVRF_E2C_DST_BACK])
31            .finalize();
32
33        ctr = next_ctr_value;
34        Some(hash_string)
35    })
36}
37
38pub(crate) fn proof_to_hash<H: digest::Digest>(
39    suite: Ciphersuite,
40    gamma_string: &[u8],
41) -> digest::Output<H> {
42    H::new()
43        .chain_update([*suite, ECVRF_PROOF_DST_FRONT])
44        .chain_update(gamma_string)
45        .chain_update([ECVRF_PROOF_DST_BACK])
46        .finalize()
47}
48
49pub(crate) fn challenge_bytes<'a, const CHALLENGE_LEN: usize, H: digest::Digest>(
50    suite: Ciphersuite,
51    points: impl Iterator<Item = &'a [u8]>,
52) -> zeroize::Zeroizing<[u8; CHALLENGE_LEN]> {
53    let mut hasher = H::new();
54    hasher.update([*suite, ECVRF_CHAL_GEN_DST_FRONT]);
55    let mut point_count = 0u8;
56    for point in points {
57        hasher.update(point);
58        point_count += 1;
59    }
60    debug_assert_eq!(point_count, 5, "Point count MUST be 5");
61    hasher.update([ECVRF_CHAL_GEN_DST_BACK]);
62    let c_string = hasher.finalize();
63
64    zeroize::Zeroizing::new(c_string[..CHALLENGE_LEN].try_into().unwrap())
65}