66
77namespace 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+
935static_assert (AffinePoint{} == 0 , " default constructed is the point at infinity" );
1036
1137bool validate (const AffinePoint& pt) noexcept
@@ -18,7 +44,19 @@ bool validate(const AffinePoint& pt) noexcept
1844
1945AffinePoint 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