Skip to content

Commit 8bba5ca

Browse files
committed
Optimize ecmul with the field endomorphism and shamir trick.
1 parent 8618070 commit 8bba5ca

1 file changed

Lines changed: 39 additions & 1 deletion

File tree

lib/evmone_precompiles/bn254.cpp

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,32 @@
66

77
namespace evmmax::bn254
88
{
9+
namespace
10+
{
11+
12+
struct Config
13+
{
14+
// Linearly independent short vectors (𝑣₁=(𝑥₁, 𝑦₁), 𝑣₂=(x₂, 𝑦₂)) such that f(𝑣₁) = f(𝑣₂) = 0,
15+
// where f : ℤ×ℤ → ℤₙ is defined as (𝑖,𝑗) → (𝑖+𝑗λ), where λ² + λ ≡ -1 mod n. n is bn245 curve
16+
// order. Here λ = 0xb3c4d79d41a917585bfc41088d8daaa78b17ea66b99c90dd. DET is (𝑣₁, 𝑣₂) matrix
17+
// determinant. For more details see https://www.iacr.org/archive/crypto2001/21390189.pdf
18+
static constexpr auto X1 = 147946756881789319020627676272574806254_u512;
19+
// Y1 should be negative, hence we calculate the determinant below adding operands instead of
20+
// subtracting.
21+
static constexpr auto Y1 = 147946756881789318990833708069417712965_u512;
22+
static constexpr auto X2 = 147946756881789319000765030803803410728_u512;
23+
static constexpr auto Y2 = 147946756881789319010696353538189108491_u512;
24+
static constexpr auto DET =
25+
43776485743678550444492811490514550177096728800832068687396408373151616991234_u256;
26+
static constexpr auto HALF = DET / 2;
27+
};
28+
29+
// For bn254 curve and β ∈ 𝔽ₚ endomorphism ϕ : E₂ → E₂ defined as (𝑥,𝑦) → (β𝑥,𝑦) calculates [λ](𝑥,𝑦)
30+
// with only one multiplication in 𝔽ₚ. BETA value in Montgomery form;
31+
inline constexpr auto BETA = ecc::FieldElement<Curve>::wrap(
32+
20006444479023397533370224967097343182639219473961804911780625968796493078869_u256);
33+
} // namespace
34+
935
static_assert(AffinePoint{} == 0, "default constructed is the point at infinity");
1036

1137
bool validate(const AffinePoint& pt) noexcept
@@ -18,7 +44,19 @@ bool validate(const AffinePoint& pt) noexcept
1844

1945
AffinePoint mul(const AffinePoint& pt, const uint256& c) noexcept
2046
{
21-
const auto pr = ecc::mul(pt, c);
47+
if (pt == 0)
48+
return pt;
49+
50+
if (c == 0)
51+
return {};
52+
53+
const auto [k1, k2] = ecc::decompose<Config>(c);
54+
55+
const auto q = AffinePoint{BETA * pt.x, !k2.first ? pt.y : -pt.y};
56+
const auto p = !k1.first ? pt : AffinePoint{pt.x, -pt.y};
57+
58+
const auto pr = shamir_multiply(k1.second, p, k2.second, q);
59+
2260
return ecc::to_affine(pr);
2361
}
2462
} // namespace evmmax::bn254

0 commit comments

Comments
 (0)