Skip to content

Commit 2ff9849

Browse files
committed
Refactor make_point
Added point type template argument.
1 parent 1a365e6 commit 2ff9849

File tree

2 files changed

+58
-32
lines changed

2 files changed

+58
-32
lines changed

include/ack/ec.hpp

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -828,10 +828,6 @@ namespace ack {
828828
[[nodiscard]] ec_point_fp_proj doubled() const
829829
{
830830
const auto& p = *this;
831-
if ( p.is_identity() ) {
832-
return p;
833-
}
834-
835831
if ( p.is_identity() || p.y == 0 ) {
836832
return ec_point_fp_proj(); // identity
837833
}
@@ -1482,11 +1478,11 @@ namespace ack {
14821478
* @param verify if true, the point is verified to be valid point on the curve created by the curve generator point g.
14831479
* @return curve point
14841480
*/
1485-
template<typename IntT = int_type>
1486-
[[nodiscard]] inline constexpr point_type make_point(IntT x, IntT y, bool verify = false) const
1481+
template<typename PointU = point_type, typename IntT = int_type>
1482+
[[nodiscard]] inline constexpr PointU make_point(IntT x, IntT y, bool verify = false) const
14871483
{
14881484
return static_cast<const CurveT&>( *this )
1489-
.make_point( std::move(x), std::move(y), verify );
1485+
.template make_point<PointU>( std::move(x), std::move(y), verify );
14901486
}
14911487

14921488
/**
@@ -1633,63 +1629,61 @@ namespace ack {
16331629
}
16341630

16351631
/**
1636-
* Creates a point from a given pair of integers x & y.
1632+
* Creates a point from provided affine coordinates x & y.
16371633
* @warning Returned point stores pointer to curve prime.
16381634
* The curve must outlive the point.
16391635
* @note Expects x|y >= 0 and x|y < p
16401636
* @note The returned point can be invalid, since the function allows
16411637
* creating points that were not generated with the generator point.
16421638
*
1639+
* @tparam PointU - point type to make. Default affine point_type.
1640+
*
16431641
* @param x - point x coordinate
16441642
* @param y - point y coordinate
16451643
* @param verify - If true, the point is verified to be valid point on the curve created by the curve generator point g.
16461644
* Default is false. Slow operation, can be be performed also with call to point.is_valid() function.
16471645
* @return Curve point
16481646
*/
1649-
[[nodiscard]] constexpr point_type make_point(IntT&& x, IntT&& y, bool verify = false) const
1647+
template<typename PointU = point_type>
1648+
[[nodiscard]] constexpr PointU make_point(IntT&& x, IntT&& y, bool verify = false) const
16501649
{
16511650
check_integer( x, "Invalid point x coordinate" );
16521651
check_integer( y, "Invalid point y coordinate" );
1653-
auto p = point_type {
1654-
*this,
1652+
auto point = make_point<PointU>(
16551653
make_field_element( std::move(x) ),
1656-
make_field_element( std::move(y) )
1657-
};
1658-
1659-
if ( verify ) {
1660-
check( p.is_valid(), "Invalid point" );
1661-
}
1662-
return p;
1654+
make_field_element( std::move(y) ),
1655+
verify
1656+
);
1657+
return point;
16631658
}
16641659

16651660
/**
1666-
* Creates a point from a given pair of integers x & y.
1661+
* Creates a point from provided affine coordinates x & y.
16671662
* @warning Returned point stores pointer to curve prime.
16681663
* The curve must outlive the point.
16691664
* @note Expects x|y >= 0 and x|y < p
16701665
* @note The returned point can be invalid, since the function allows
16711666
* creating points that were not generated with the generator point.
16721667
*
1668+
* @tparam PointU - point type to make. Default affine point_type.
1669+
*
16731670
* @param x - point x coordinate
16741671
* @param y - point y coordinate
16751672
* @param verify - If true, the point is verified to be valid point on the curve created by the curve generator point g.
16761673
* Default is false. Slow operation, can be be performed also with call to point.is_valid() function.
16771674
* @return Curve point
16781675
*/
1679-
[[nodiscard]] constexpr point_type make_point(const IntT& x, const IntT& y, bool verify = false) const
1676+
template<typename PointU = point_type>
1677+
[[nodiscard]] constexpr PointU make_point(const IntT& x, const IntT& y, bool verify = false) const
16801678
{
16811679
check_integer( x, "Invalid point x coordinate" );
16821680
check_integer( y, "Invalid point y coordinate" );
1683-
auto p = point_type {
1684-
*this,
1681+
auto point = make_point<PointU>(
16851682
make_field_element( x, /*verify=*/ false ),
1686-
make_field_element( y, /*verify=*/ false )
1687-
};
1688-
1689-
if ( verify ) {
1690-
check( p.is_valid(), "Invalid point" );
1691-
}
1692-
return p;
1683+
make_field_element( y, /*verify=*/ false ),
1684+
verify
1685+
);
1686+
return point;
16931687
}
16941688

16951689
/**
@@ -1723,9 +1717,6 @@ namespace ack {
17231717
auto afe = make_field_element( a, /*verify =*/ false );
17241718
auto bfe = make_field_element( b, /*verify =*/ false );
17251719
auto y2 = 4 * afe.sqr() * afe + 27 * bfe.sqr();
1726-
if ( y2 == 0 ) {
1727-
return false;
1728-
}
17291720

17301721
// check that discriminant is nonzero. If zero, the curve is singular.
17311722
if ( ( -16 * y2 ) == 0) {
@@ -1781,6 +1772,21 @@ namespace ack {
17811772
}
17821773
return field_element_type( x, p );
17831774
}
1775+
1776+
template<typename PointU>
1777+
[[nodiscard]] constexpr PointU make_point(field_element_type x, field_element_type y, bool verify = false) const
1778+
{
1779+
auto point = PointU{ point_type {
1780+
*this,
1781+
std::move( x ),
1782+
std::move( y )
1783+
}};
1784+
1785+
if ( verify ) {
1786+
check( point.is_valid(), "Invalid point" );
1787+
}
1788+
return point;
1789+
}
17841790
};
17851791

17861792
/**

tests/include/ack/tests/ec_test.hpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,17 @@ namespace ack::tests {
142142
REQUIRE_EQUAL( p1.is_valid() , false )
143143

144144
auto p1_proj = ec_point_fp_proj( p1 );
145+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y ), p1_proj )
146+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y, /*verify=*/ false ), p1_proj )
145147
REQUIRE_EQUAL( ( p1_proj.x == 0 ) && ( p1_proj.y == 1 ) && ( p1_proj.z == 0 ), true )
146148
REQUIRE_EQUAL( p1_proj.is_identity(), true )
147149
REQUIRE_EQUAL( p1_proj.is_on_curve(), true )
148150
REQUIRE_EQUAL( p1_proj.is_valid() , false )
149151
REQUIRE_EQUAL( p1_proj.to_affine() , p1 )
150152

151153
auto p1_jacobi = ec_point_fp_jacobi( p1 );
154+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y ), p1_jacobi )
155+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y, /*verify=*/ false ), p1_jacobi )
152156
REQUIRE_EQUAL( ( p1_jacobi.x == 0 ) && ( p1_jacobi.y == 1 ) && ( p1_jacobi.z == 0 ), true )
153157
REQUIRE_EQUAL( p1_jacobi.is_identity(), true )
154158
REQUIRE_EQUAL( p1_jacobi.is_on_curve(), true )
@@ -176,13 +180,17 @@ namespace ack::tests {
176180
REQUIRE_EQUAL( p1.is_valid() , false )
177181

178182
auto p1_proj = ec_point_fp_proj( p1 );
183+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y ), p1_proj )
184+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y, /*verify=*/ false ) , p1_proj )
179185
REQUIRE_EQUAL( ( p1_proj.x == 3 ) && ( p1_proj.y == 7 ) && ( p1_proj.z == 1 ), true )
180186
REQUIRE_EQUAL( p1_proj.is_identity(), false )
181187
REQUIRE_EQUAL( p1_proj.is_on_curve(), false )
182188
REQUIRE_EQUAL( p1_proj.is_valid() , false )
183189
REQUIRE_EQUAL( p1_proj.to_affine() , p1 )
184190

185191
auto p1_jacobi = ec_point_fp_jacobi( p1 );
192+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y ), p1_jacobi )
193+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y, /*verify=*/ false ), p1_jacobi )
186194
REQUIRE_EQUAL( ( p1_jacobi.x == 3 ) && ( p1_jacobi.y == 7 ) && ( p1_jacobi.z == 1 ), true )
187195
REQUIRE_EQUAL( p1_jacobi.is_identity(), false )
188196
REQUIRE_EQUAL( p1_jacobi.is_on_curve(), false )
@@ -210,13 +218,17 @@ namespace ack::tests {
210218
REQUIRE_EQUAL( p1.is_valid() , false ) // point not generated by base point
211219

212220
auto p1_proj = ec_point_fp_proj( p1 );
221+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y ), p1_proj )
222+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y ), p1_proj )
213223
REQUIRE_EQUAL( ( p1_proj.x == 3 ) && ( p1_proj.y == 10 ) && ( p1_proj.z == 1 ), true )
214224
REQUIRE_EQUAL( p1_proj.is_identity(), false )
215225
REQUIRE_EQUAL( p1_proj.is_on_curve(), true )
216226
REQUIRE_EQUAL( p1_proj.is_valid() , false ) // point not generated by base point
217227
REQUIRE_EQUAL( p1_proj.to_affine() , p1 )
218228

219229
auto p1_jacobi = ec_point_fp_jacobi( p1 );
230+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y ), p1_jacobi )
231+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y ), p1_jacobi )
220232
REQUIRE_EQUAL( ( p1_jacobi.x == 3 ) && ( p1_jacobi.y == 10 ) && ( p1_jacobi.z == 1 ), true )
221233
REQUIRE_EQUAL( p1_jacobi.is_identity(), false )
222234
REQUIRE_EQUAL( p1_jacobi.is_on_curve(), true )
@@ -244,13 +256,17 @@ namespace ack::tests {
244256
REQUIRE_EQUAL( p1.is_valid() , false )
245257

246258
auto p1_proj = ec_point_fp_proj( p1 );
259+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y ), p1_proj )
260+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y, /*verify=*/ false ), p1_proj )
247261
REQUIRE_EQUAL( ( p1_proj.x == 22 ) && ( p1_proj.y == 22 ) && ( p1_proj.z == 1 ), true )
248262
REQUIRE_EQUAL( p1_proj.is_identity(), false )
249263
REQUIRE_EQUAL( p1_proj.is_on_curve(), false )
250264
REQUIRE_EQUAL( p1_proj.is_valid() , false )
251265
REQUIRE_EQUAL( p1_proj.to_affine() , p1 )
252266

253267
auto p1_jacobi = ec_point_fp_jacobi( p1 );
268+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y ), p1_jacobi )
269+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y, /*verify=*/ false ), p1_jacobi )
254270
REQUIRE_EQUAL( ( p1_jacobi.x == 22 ) && ( p1_jacobi.y == 22 ) && ( p1_jacobi.z == 1 ), true )
255271
REQUIRE_EQUAL( p1_jacobi.is_identity(), false )
256272
REQUIRE_EQUAL( p1_jacobi.is_on_curve(), false )
@@ -278,12 +294,16 @@ namespace ack::tests {
278294
REQUIRE_EQUAL( p1.is_valid() , true )
279295

280296
auto p1_proj = ec_point_fp_proj( p1 );
297+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y ), p1_proj )
298+
REQUIRE_EQUAL( c23.make_point<c23_point_proj>( x, y, /*verify=*/ true ), p1_proj )
281299
REQUIRE_EQUAL( ( p1_proj.x == 5 ) && ( p1_proj.y == 4 ) && ( p1_proj.z == 1 ), true )
282300
REQUIRE_EQUAL( p1_proj.is_identity(), false )
283301
REQUIRE_EQUAL( p1_proj.is_on_curve(), true )
284302
REQUIRE_EQUAL( p1_proj.is_valid() , true )
285303

286304
auto p1_jacobi = ec_point_fp_jacobi( p1 );
305+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y, /*verify=*/ false ), p1_jacobi )
306+
REQUIRE_EQUAL( c23.make_point<c23_point_jacobi>( x, y, /*verify=*/ true ), p1_jacobi )
287307
REQUIRE_EQUAL( ( p1_jacobi.x == 5 ) && ( p1_jacobi.y == 4 ) && ( p1_jacobi.z == 1 ), true )
288308
REQUIRE_EQUAL( p1_jacobi.is_identity(), false )
289309
REQUIRE_EQUAL( p1_jacobi.is_on_curve(), true )

0 commit comments

Comments
 (0)