From 0ac60fa6cb33e62beb1a7d26076a83bf6966f59d Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Thu, 12 Feb 2026 10:30:12 -0500 Subject: [PATCH 1/2] perf(crypto): Small optimizations for Lagrange interpolation Avoiding clones is various scenarious, also compare indices rather than the Scalar coefficient values in the main loop. --- .../crypto_lib/bls12_381/type/src/interpolation.rs | 12 +++++++++--- .../src/ni_dkg/groth20_bls12_381/transcript.rs | 3 +-- .../bls12_381/src/types/public_coefficients.rs | 3 +-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/rs/crypto/internal/crypto_lib/bls12_381/type/src/interpolation.rs b/rs/crypto/internal/crypto_lib/bls12_381/type/src/interpolation.rs index 16be0203e198..61c53a908f58 100644 --- a/rs/crypto/internal/crypto_lib/bls12_381/type/src/interpolation.rs +++ b/rs/crypto/internal/crypto_lib/bls12_381/type/src/interpolation.rs @@ -120,9 +120,10 @@ impl LagrangeCoefficients { // 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 = Scalar::one(); - let x_i = samples[i].clone(); - for x_j in samples.iter().filter(|x_j| **x_j != x_i) { - denom *= x_j - &x_i; + for (j, x_j) in samples.iter().enumerate() { + if j != i { + denom *= x_j - &samples[i]; + } } denominator.push(denom); @@ -152,6 +153,11 @@ impl LagrangeCoefficients { &self.coefficients } + /// Return the Lagrange coefficients, consuming self + pub fn into_coefficients(self) -> Vec { + self.coefficients + } + /// Given a list of samples `(x, f(x) * g)` for a set of unique `x`, some /// polynomial `f`, and some integer `g`, returns `f(value) * g`. /// diff --git a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs index f32307107a36..084f8734d2c1 100644 --- a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs +++ b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs @@ -207,8 +207,7 @@ fn compute_transcript( .expect("Cannot fail because all x are distinct."); LagrangeCoefficients::at_zero(&indices) - .coefficients() - .to_vec() + .into_coefficients() }; let mut combined = vec![]; diff --git a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs index 1a36b49cc913..f64d816cc5e3 100644 --- a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs +++ b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs @@ -124,8 +124,7 @@ impl PublicCoefficients { let indices = NodeIndices::from_slice(samples).map_err(|_| ThresholdError::DuplicateX)?; Ok(LagrangeCoefficients::at_zero(&indices) - .coefficients() - .to_vec()) + .into_coefficients()) } } From 8d6975296aa1a7930f87373dc804efe0f12ae122 Mon Sep 17 00:00:00 2001 From: IDX GitHub Automation Date: Thu, 12 Feb 2026 15:36:36 +0000 Subject: [PATCH 2/2] Automatically fixing code for linting and formatting issues --- .../bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs | 3 +-- .../threshold_sig/bls12_381/src/types/public_coefficients.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs index 084f8734d2c1..b52bf56182d9 100644 --- a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs +++ b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/ni_dkg/groth20_bls12_381/transcript.rs @@ -206,8 +206,7 @@ fn compute_transcript( let indices = NodeIndices::from_slice(&reshare_x) .expect("Cannot fail because all x are distinct."); - LagrangeCoefficients::at_zero(&indices) - .into_coefficients() + LagrangeCoefficients::at_zero(&indices).into_coefficients() }; let mut combined = vec![]; diff --git a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs index f64d816cc5e3..4f4b82cc7d8a 100644 --- a/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs +++ b/rs/crypto/internal/crypto_lib/threshold_sig/bls12_381/src/types/public_coefficients.rs @@ -123,8 +123,7 @@ impl PublicCoefficients { let indices = NodeIndices::from_slice(samples).map_err(|_| ThresholdError::DuplicateX)?; - Ok(LagrangeCoefficients::at_zero(&indices) - .into_coefficients()) + Ok(LagrangeCoefficients::at_zero(&indices).into_coefficients()) } }