Skip to content

Commit cf2bbe7

Browse files
authored
crypto: Replace BaseFieldElem with FieldElement (#1417)
1 parent f71d9da commit cf2bbe7

5 files changed

Lines changed: 16 additions & 85 deletions

File tree

lib/evmone_precompiles/ecc.hpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ template <typename T>
2626
concept FieldSpec = requires { T::ORDER; };
2727

2828
/// A representation of an element in a prime field.
29-
///
30-
/// TODO: Combine with BaseFieldElem.
3129
template <FieldSpec Spec>
3230
class FieldElement
3331
{
@@ -112,6 +110,12 @@ class FieldElement
112110
{
113111
return wrap(Fp.mul(a.value_, Fp.inv(b.value_)));
114112
}
113+
114+
/// Named 1/x inversion method. Needed in the pairing templates.
115+
constexpr auto inv() const noexcept { return wrap(Fp.inv(value_)); }
116+
117+
/// Named one element. Needed in the pairing templates.
118+
static constexpr auto one() noexcept { return FieldElement{1}; }
115119
};
116120

117121
/// The affine (two coordinates) point on an Elliptic Curve over a prime field.

lib/evmone_precompiles/pairing/bn254/fields.hpp

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,7 @@
1010
namespace evmmax::bn254
1111
{
1212
using namespace intx;
13-
14-
/// Specifies base field value type and modular arithmetic for bn254 curve.
15-
struct BaseFieldConfig
16-
{
17-
using ValueT = uint256;
18-
static constexpr auto MOD_ARITH = ModArith{Curve::FIELD_PRIME};
19-
static constexpr auto ONE = MOD_ARITH.to_mont(1);
20-
};
21-
using Fq = ecc::BaseFieldElem<BaseFieldConfig>;
13+
using Fq = Curve::Fp;
2214

2315
// Extension fields implemented based on https://hackmd.io/@jpw/bn254#Field-extension-towers
2416

@@ -39,10 +31,10 @@ struct Fq6Config
3931
using BaseFieldT = Fq;
4032
using ValueT = Fq2;
4133
static constexpr uint8_t DEGREE = 3;
42-
static constexpr auto ksi = Fq2({Fq::from_int(9_u256), Fq::from_int(1_u256)});
34+
static constexpr auto ksi = Fq2({Fq(9_u256), Fq(1_u256)});
4335
static constexpr auto _3_ksi_inv = Fq2({
44-
Fq::from_int(0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5_u256),
45-
Fq::from_int(0x9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2_u256),
36+
Fq(0x2b149d40ceb8aaae81be18991be06ac3b5b4c5e559dbefa33267e6dc24a138e5_u256),
37+
Fq(0x9713b03af0fed4cd2cafadeed8fdf4a74fa084e52d1852e4a2bd0685c315d2_u256),
4638
});
4739
};
4840
using Fq6 = ecc::ExtFieldElem<Fq6Config>;
@@ -110,12 +102,6 @@ constexpr Fq12 multiply(const Fq12& a, const Fq12& b)
110102
return Fq12({c0, c1});
111103
}
112104

113-
/// Inverses the base field element
114-
inline Fq inverse(const Fq& x)
115-
{
116-
return Fq(BaseFieldConfig::MOD_ARITH.inv(x.value()));
117-
}
118-
119105
/// Inverses the Fq^2 field element
120106
inline Fq2 inverse(const Fq2& f)
121107
{

lib/evmone_precompiles/pairing/bn254/pairing.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ std::optional<bool> pairing_check(std::span<const std::pair<Point, ExtPoint>> pa
145145
}
146146

147147
// Converts points' coefficients in Montgomery form.
148-
const auto P_aff = ecc::Point<Fq>{Fq::from_int(p.x), Fq::from_int(p.y)};
149-
const auto Q_aff = ecc::Point<Fq2>{Fq2({Fq::from_int(q.x.first), Fq::from_int(q.x.second)}),
150-
Fq2({Fq::from_int(q.y.first), Fq::from_int(q.y.second)})};
148+
const auto P_aff = ecc::Point<Fq>{Fq(p.x), Fq(p.y)};
149+
const auto Q_aff = ecc::Point<Fq2>{
150+
Fq2({Fq(q.x.first), Fq(q.x.second)}), Fq2({Fq(q.y.first), Fq(q.y.second)})};
151151

152152
const bool g1_is_inf = is_infinity(P_aff);
153153
const bool g2_is_inf = g2_is_infinity(Q_aff);

lib/evmone_precompiles/pairing/bn254/utils.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace evmmax::bn254
99
{
1010
consteval Fq2 make_fq2(const uint256& a, const uint256& b) noexcept
1111
{
12-
return Fq2({Fq::from_int(a), Fq::from_int(b)});
12+
return Fq2({Fq(a), Fq(b)});
1313
}
1414

1515
/// Defines coefficients needed for fast Frobenius endomorphism computation.
@@ -77,7 +77,7 @@ constexpr bool is_field_element(const uint256& v)
7777
constexpr bool is_on_curve(const ecc::Point<Fq>& p) noexcept
7878
{
7979
// TODO(C++23): make static
80-
constexpr auto B = Fq::from_int(3);
80+
constexpr auto B = Fq(3);
8181

8282
const auto x3 = p.x * p.x * p.x;
8383
const auto y2 = p.y * p.y;
@@ -96,7 +96,7 @@ constexpr bool is_on_twisted_curve(const evmmax::ecc::Point<Fq2>& p)
9696
/// Verifies that affine point over the base field is infinity.
9797
constexpr bool is_infinity(const evmmax::ecc::Point<Fq>& p)
9898
{
99-
return p.x.is_zero() && p.y.is_zero();
99+
return p.x == 0 && p.y == 0;
100100
}
101101

102102
/// Verifies that affine point over the Fq^2 extended field is infinity.

lib/evmone_precompiles/pairing/field_template.hpp

Lines changed: 0 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -7,65 +7,6 @@
77

88
namespace evmmax::ecc
99
{
10-
/// Implements computations over base field defined by prime number.
11-
/// Wraps around ModArith struct and implements additional functions needed for pairing.
12-
/// It is a template struct which can be reused for different pairing implementations.
13-
template <typename ConfigT>
14-
class BaseFieldElem
15-
{
16-
using ValueT = typename ConfigT::ValueT;
17-
18-
static constexpr ModArith<ValueT> Fp = ConfigT::MOD_ARITH;
19-
20-
ValueT m_value;
21-
22-
public:
23-
constexpr BaseFieldElem() noexcept = default;
24-
25-
explicit constexpr BaseFieldElem(const ValueT& v) noexcept : m_value(v) {}
26-
27-
static constexpr BaseFieldElem from_int(const ValueT& v) noexcept
28-
{
29-
return BaseFieldElem(Fp.to_mont(v));
30-
}
31-
32-
constexpr const ValueT& value() const noexcept { return m_value; }
33-
34-
BaseFieldElem inv() const noexcept { return inverse(*this); }
35-
36-
constexpr bool is_zero() const noexcept { return m_value == 0; }
37-
38-
static constexpr BaseFieldElem one() noexcept { return BaseFieldElem(ConfigT::ONE); }
39-
40-
static constexpr BaseFieldElem zero() noexcept { return BaseFieldElem(0); }
41-
42-
friend constexpr BaseFieldElem operator+(
43-
const BaseFieldElem& e1, const BaseFieldElem& e2) noexcept
44-
{
45-
return BaseFieldElem(Fp.add(e1.m_value, e2.m_value));
46-
}
47-
48-
friend constexpr BaseFieldElem operator-(
49-
const BaseFieldElem& e1, const BaseFieldElem& e2) noexcept
50-
{
51-
return BaseFieldElem(Fp.sub(e1.m_value, e2.m_value));
52-
}
53-
54-
friend constexpr BaseFieldElem operator*(
55-
const BaseFieldElem& e1, const BaseFieldElem& e2) noexcept
56-
{
57-
return BaseFieldElem(Fp.mul(e1.m_value, e2.m_value));
58-
}
59-
60-
friend constexpr BaseFieldElem operator-(const BaseFieldElem& e) noexcept
61-
{
62-
return BaseFieldElem(Fp.sub(ValueT{0}, e.m_value));
63-
}
64-
65-
friend constexpr bool operator==(
66-
const BaseFieldElem& e1, const BaseFieldElem& e2) noexcept = default;
67-
};
68-
6910
/// Implements extension field over the base field or other extension fields.
7011
/// It is a template struct which can be reused for different pairing implementations.
7112
template <typename ConfigT>

0 commit comments

Comments
 (0)