@@ -8,15 +8,14 @@ namespace evmmax::secp256k1
88{
99namespace
1010{
11- constexpr auto B = ecc::FieldElement<Curve> {7 };
11+ constexpr auto B = Curve::Fp {7 };
1212
1313constexpr AffinePoint G{0x79be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798_u256,
1414 0x483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8_u256};
1515} // namespace
1616
1717// FIXME: Change to "uncompress_point".
18- std::optional<ecc::FieldElement<Curve>> calculate_y (
19- const ecc::FieldElement<Curve>& x, bool y_parity) noexcept
18+ std::optional<Curve::Fp> calculate_y (const Curve::Fp& x, bool y_parity) noexcept
2019{
2120 // Calculate y = √(x³ + 7).
2221 const auto xxx = x * x * x;
@@ -50,43 +49,39 @@ std::optional<AffinePoint> secp256k1_ecdsa_recover(std::span<const uint8_t, 32>
5049 // Follows "Elliptic Curve Digital Signature Algorithm - Public key recovery"
5150 // https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm#Public_key_recovery
5251
53- const auto r = intx::be::unsafe::load<uint256>(r_bytes.data ());
54- const auto s = intx::be::unsafe::load<uint256>(s_bytes.data ());
55-
5652 // 1. Validate r and s are within [1, n-1].
57- if (r == 0 || r >= Curve::ORDER || s == 0 || s >= Curve::ORDER ) [[unlikely]]
53+ const auto opt_r = Curve::Fr::from_bytes (r_bytes);
54+ if (!opt_r.has_value () || *opt_r == 0 ) [[unlikely]]
55+ return std::nullopt ;
56+
57+ const auto opt_s = Curve::Fr::from_bytes (s_bytes);
58+ if (!opt_s.has_value () || *opt_s == 0 ) [[unlikely]]
5859 return std::nullopt ;
5960
61+ const auto & r = *opt_r;
62+ const auto & s = *opt_s;
63+
6064 // 3. Hash of the message is already calculated in e.
6165 // 4. Convert hash e to z field element by doing z = e % n.
6266 // https://www.rfc-editor.org/rfc/rfc6979#section-2.3.2
6367 // Converting to Montgomery form performs the e % n reduction.
64- const ModArith n{Curve::ORDER };
65- const auto z = intx::be::unsafe::load<uint256>(hash.data ());
66- const auto z_mont = n.to_mont (z);
68+ const auto z = Curve::Fr{intx::be::unsafe::load<uint256>(hash.data ())};
6769
6870 // 5. Calculate u1 and u2.
69- const auto r_n = n.to_mont (r);
70- const auto r_inv = n.inv (r_n);
71-
72- const auto z_neg = n.sub (0 , z_mont);
73- const auto u1_mont = n.mul (z_neg, r_inv);
74- const auto u1 = n.from_mont (u1_mont);
75-
76- const auto s_mont = n.to_mont (s);
77- const auto u2_mont = n.mul (s_mont, r_inv);
78- const auto u2 = n.from_mont (u2_mont);
71+ const auto r_inv = 1 / r;
72+ const auto u1 = -z * r_inv;
73+ const auto u2 = s * r_inv;
7974 assert (u2 != 0 ); // Because s != 0 and r_inv != 0.
8075
8176 // 2. Calculate y coordinate of R from r and v.
82- const auto r_mont = ecc::FieldElement<Curve>{r };
77+ const auto r_mont = Curve::Fp{r. value () };
8378 const auto y = calculate_y (r_mont, parity);
84- if (!y.has_value ()) [[unlikely]]
79+ if (!y.has_value ())
8580 return std::nullopt ;
8681
8782 // 6. Calculate public key point Q = u1×G + u2×R.
8883 const auto R = AffinePoint{r_mont, *y};
89- const auto Q = msm (u1, G, u2, R);
84+ const auto Q = msm (u1. value () , G, u2. value () , R);
9085
9186 // The public key mustn't be the point at infinity. This check is cheaper on a non-affine point.
9287 if (Q == 0 ) [[unlikely]]
@@ -107,7 +102,7 @@ std::optional<evmc::address> ecrecover(std::span<const uint8_t, 32> hash,
107102 return to_address (*pubkey);
108103}
109104
110- std::optional<ecc::FieldElement<Curve>> field_sqrt (const ecc::FieldElement<Curve> & x) noexcept
105+ std::optional<Curve::Fp> field_sqrt (const Curve::Fp & x) noexcept
111106{
112107 // Computes modular exponentiation
113108 // x^0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffbfffff0c
@@ -138,11 +133,11 @@ std::optional<ecc::FieldElement<Curve>> field_sqrt(const ecc::FieldElement<Curve
138133 // return ((x223 << 23 + x22) << 6 + _11) << 2
139134
140135 // Allocate Temporaries.
141- ecc::FieldElement<Curve> z;
142- ecc::FieldElement<Curve> t0;
143- ecc::FieldElement<Curve> t1;
144- ecc::FieldElement<Curve> t2;
145- ecc::FieldElement<Curve> t3;
136+ Curve::Fp z;
137+ Curve::Fp t0;
138+ Curve::Fp t1;
139+ Curve::Fp t2;
140+ Curve::Fp t3;
146141
147142
148143 // Step 1: z = x^0x2
0 commit comments