coconut_crypto/helpers/
mod.rs

1//! Miscellaneous helpers and re-exports from `dock_crypto_utils`.
2
3use alloc::{format, string::String, vec::Vec};
4
5use ark_ff::PrimeField;
6
7#[cfg(feature = "parallel")]
8use rayon::prelude::*;
9
10use ark_std::{cfg_into_iter, cfg_iter};
11
12use schnorr_pok::error::SchnorrError;
13
14pub mod with_schnorr_and_blindings;
15pub mod with_schnorr_response;
16
17pub use utils::{
18    aliases::*, extend_some::*, iter::*, misc::*, owned_pairs::*, pairs::*, try_iter::*,
19};
20pub use with_schnorr_and_blindings::*;
21pub use with_schnorr_response::*;
22
23use utils::{impl_indexed_iter, impl_into_indexed_iter, join};
24
25/// TODO remove when `SchnorrError` will derive `Eq`, `PartialEq`, `Clone`
26pub fn schnorr_error(err: SchnorrError) -> String {
27    format!("{:?}", err)
28}
29
30/// `l_{i ∈ S} = \prod_{j ∈ S, j != i}((0 - j) / (i - j))`
31#[allow(non_snake_case)]
32pub fn lagrange_basis_at_0<F: PrimeField>(
33    S: impl_into_indexed_iter!(<Item = impl Into<F>>),
34) -> impl_indexed_iter!(<Item = F>) {
35    let items: Vec<_> = cfg_into_iter!(S).map(Into::into).collect();
36    let all_i_prod: F = cfg_iter!(items).product();
37
38    cfg_into_iter!(items.clone()).map(move |i| {
39        let (num, den) = join!(all_i_prod / i, {
40            let mut prod: F = cfg_iter!(items)
41                .filter(|&j| &i != j)
42                .map(|&j| j - i)
43                .product();
44            prod.inverse_in_place().unwrap();
45
46            prod
47        });
48
49        num * den
50    })
51}