diff --git a/lib/evmone_precompiles/pairing/bn254/fields.hpp b/lib/evmone_precompiles/pairing/bn254/fields.hpp index aaaddcb448..98bd0748d6 100644 --- a/lib/evmone_precompiles/pairing/bn254/fields.hpp +++ b/lib/evmone_precompiles/pairing/bn254/fields.hpp @@ -59,6 +59,16 @@ constexpr Fq2 multiply(const Fq2& a, const Fq2& b) return Fq2({a0 * b0 - a1 * b1, a1 * b0 + a0 * b1}); } +/// Squares an Fq^2 field element. +constexpr Fq2 sqr(const Fq2& a) +{ + const auto& [a0, a1] = a.coeffs; + + // (a0 + a1*u)^2 = (a0+a1)*(a0-a1) + 2a0a1*u. + const auto a0a1 = a0 * a1; + return Fq2({(a0 + a1) * (a0 - a1), a0a1 + a0a1}); +} + /// Multiplies two Fq^6 field elements constexpr Fq6 multiply(const Fq6& a, const Fq6& b) { diff --git a/lib/evmone_precompiles/pairing/field_template.hpp b/lib/evmone_precompiles/pairing/field_template.hpp index e347a77499..50af9fcddc 100644 --- a/lib/evmone_precompiles/pairing/field_template.hpp +++ b/lib/evmone_precompiles/pairing/field_template.hpp @@ -68,8 +68,14 @@ struct ExtFieldElem return ExtFieldElem(ret); } - friend constexpr ExtFieldElem operator*(const ExtFieldElem& e1, const ExtFieldElem& e2) noexcept + [[gnu::always_inline]] friend constexpr ExtFieldElem operator*( + const ExtFieldElem& e1, const ExtFieldElem& e2) noexcept { + if constexpr (requires { sqr(e1); }) // Use sqr() if available. + { + if (&e1 == &e2) + return sqr(e1); + } return multiply(e1, e2); }