pub fn lagrange_coefficients_at_zero(
    samples: &[EccScalar],
) -> Result<Vec<EccScalar>, ThresholdEcdsaError> {
    if samples.is_empty() {
        return Ok(vec![]);
    }

    let curve = samples[0].curve_type();

    for sample in samples {
        if sample.curve_type() != curve {
            return Err(ThresholdEcdsaError::CurveMismatch);
        }
    }

    if samples.len() == 1 {
        return Ok(vec![EccScalar::one(curve)]);
    }

    if contains_duplicates(samples) {
        return Err(ThresholdEcdsaError::InterpolationError);
    }

    // The j'th numerator is the product of all `x_prod[i]` for `i!=j`.
    // Note: The usual subtractions can be omitted as we are computing the Lagrange
    // coefficient at zero.
    let mut x_prod = Vec::with_capacity(samples.len());
    let mut tmp = EccScalar::one(curve);
    x_prod.push(tmp);
    for x in samples.iter().take(samples.len() - 1) {
        tmp = tmp.mul(x)?;
        x_prod.push(tmp);
    }
    tmp = EccScalar::one(curve);
    for (i, x) in samples[1..].iter().enumerate().rev() {
        tmp = tmp.mul(x)?;
        x_prod[i] = x_prod[i].mul(&tmp)?;
    }

    for (lagrange_i, x_i) in x_prod.iter_mut().zip(samples) {
        // Compute the value at 0 of the i-th Lagrange polynomial that is `0` at the
        // other data points but `1` at `x_i`.
        let mut denom = EccScalar::one(curve);
        for x_j in samples.iter().filter(|x_j| *x_j != x_i) {
            let diff = x_j.sub(x_i)?;
            denom = denom.mul(&diff)?;
        }
        let inv = denom.invert()?;

        if inv.is_zero() {
            return Err(ThresholdEcdsaError::InterpolationError);
        }

        *lagrange_i = lagrange_i.mul(&inv)?;
    }
    Ok(x_prod)
}
/// Compute the Lagrange coefficients at x=0.
///
/// # Arguments
/// * `samples` is a list of values x_0, x_1, ...x_n.
/// # Result
/// * `[lagrange_0, lagrange_1, ..., lagrange_n]` where:
///    * lagrange_i = numerator_i/denominator_i
///    * numerator_i = x_0 * x_1 * ... * x_(i-1) * x_(i+1) * ... * x_n
///    * denominator_i = (x_0 - x_i) * (x_1 - x_i) * ... * (x_(i-1) - x_i) *
///      (x_(i+1) - x_i) * ... * (x_n - x_i)
/// # Errors
/// This will return an error if the denominator is zero.
Compute the Lagrange coefficients at x=0.
Compute the Lagrange coefficients at x = 0 .
pub fn lagrange_coefficients_at_zero(
    samples: &[EccScalar],
) -> Result<Vec<EccScalar>, ThresholdEcdsaError> {
    if samples.is_empty() {
        return Ok(vec![]);
    }
    let curve = samples[0].curve_type();
    for sample in samples {
        if sample.curve_type() != curve {
            return Err(ThresholdEcdsaError::CurveMismatch);
        }
    }
    if samples.len() == 1 {
        return Ok(vec![EccScalar::one(curve)]);
    }
    if contains_duplicates(samples) {
        return Err(ThresholdEcdsaError::InterpolationError);
    }
    // The j'th numerator is the product of all `x_prod[i]` for `i!=j`.
    // Note: The usual subtractions can be omitted as we are computing the Lagrange
    // coefficient at zero.
    let mut x_prod = Vec::with_capacity(samples.len());
    let mut tmp = EccScalar::one(curve);
    x_prod.push(tmp);
    for x in samples.iter().take(samples.len() - 1) {
        tmp = tmp.mul(x)?;
        x_prod.push(tmp);
    }
    tmp = EccScalar::one(curve);
    for (i, x) in samples[1..].iter().enumerate().rev() {
        tmp = tmp.mul(x)?;
        x_prod[i] = x_prod[i].mul(&tmp)?;
    }
    for (lagrange_i, x_i) in x_prod.iter_mut().zip(samples) {
        // Compute the value at 0 of the i-th Lagrange polynomial that is `0` at the
        // other data points but `1` at `x_i`.
        let mut denom = EccScalar::one(curve);
        for x_j in samples.iter().filter(|x_j| *x_j != x_i) {
            let diff = x_j.sub(x_i)?;
            denom = denom.mul(&diff)?;
        }
        let inv = denom.invert()?;
        if inv.is_zero() {
            return Err(ThresholdEcdsaError::InterpolationError);
        }
        *lagrange_i = lagrange_i.mul(&inv)?;
    }
    Ok(x_prod)
}
pub fn lagrange_coefficients_at_zero ( samples : & [ EccScalar ] , ) -> Result < Vec < EccScalar > , ThresholdEcdsaError > { if samples . is_empty ( ) { return Ok ( vec ! [ ] ) ; } let curve = samples [ 0 ] . curve_type ( ) ; for sample in samples { if sample . curve_type ( ) != curve { return Err ( ThresholdEcdsaError :: CurveMismatch ) ; } } if samples . len ( ) == 1 { return Ok ( vec ! [ EccScalar one ( curve ) ] ) ; } if contains_duplicates ( samples ) { return Err ( ThresholdEcdsaError :: InterpolationError ) ; } // The j'th numerator is the product of all `x_prod[i]` for `i!=j`. // Note: The usual subtractions can be omitted as we are computing the Lagrange // coefficient at zero. let mut x_prod = Vec :: with_capacity ( samples . len ( ) ) ; let mut tmp = EccScalar :: one ( curve ) ; x_prod . push ( tmp ) ; for x in samples . iter ( ) . take ( samples . len ( ) - 1 ) { tmp = tmp . mul ( x ) ? ; x_prod . push ( tmp ) ; } tmp = EccScalar :: one ( curve ) ; for ( i , x ) in samples [ 1 .. ] . iter ( ) . enumerate ( ) . rev ( ) { tmp = tmp . mul ( x ) ? ; x_prod [ i ] = x_prod [ i ] . mul ( & tmp ) ? ; } for ( lagrange_i , x_i ) in x_prod . iter_mut ( ) . zip ( samples ) { // Compute the value at 0 of the i-th Lagrange polynomial that is `0` at the // other data points but `1` at `x_i`. let mut denom = EccScalar :: one ( curve ) ; for x_j in samples . iter ( ) . filter ( | x_j | * x_j != x_i ) { let diff = x_j . sub ( x_i ) ? ; denom = denom . mul ( & diff ) ? ; } let inv = denom . invert ( ) ? ; if inv . is_zero ( ) { return Err ( ThresholdEcdsaError :: InterpolationError ) ; } * lagrange_i = lagrange_i . mul ( & inv ) ? ; } Ok ( x_prod ) }
Compute the Lagrange coefficients at x=0.
Compute the Lagrange coefficients at x = 0 .
samples
&[EccScalar]
samples
&[EccScalar]
result
`[lagrange_0, lagrange_1, ..., lagrange_n]` where:
lagrange_i = numerator_i/denominator_i
numerator_i = x_0 * x_1 * ...
` [ lagrange_0 lagrange_1 ... lagrange_n ] ` where : lagrange_i = numerator_i / denominator_i numerator_i = x_0 * x_1 * ...
errors
This will return an error if the denominator is zero.
This will return an error if the denominator is zero .