Created
November 24, 2019 05:13
-
-
Save HarryR/f1b74708622f394b9b7b7a34f61d5817 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Conditionally enable a function if they share the same CurveT type | |
/// e.g. template<IsSameCurve<CurveT,OtherType> = 0> | |
template<typename MyCurve, typename OtherType> | |
using IsSameCurve = std::enable_if_t<std::is_same<MyCurve,typename OtherType::CurveT>::value,int>; | |
/// Conditionally enable a function if the are of the same types and curves | |
/// Uses CanonicalSelfT to determine if they're the same general type | |
/// e.g. template<IsSameCurve<CurveT,OtherType> = 0> | |
template<typename SelfT, typename OtherT> | |
using IsSamePointType = std::enable_if_t< | |
std::is_same<typename SelfT::CanonicalSelfT,typename OtherT::CanonicalSelfT>::value | |
,int>; | |
template<typename _CurveT, typename XT, typename YT = XT> | |
struct SwAffinePoint; | |
template<typename SelfT, typename OtherT> | |
using IsAffineType = std::enable_if_t< | |
std::is_same<typename OtherT::CanonicalSelfT, SwAffinePoint<typename SelfT::CurveT,int,int>>::value | |
,int>; | |
template<typename _CurveT, typename XT, typename YT = XT, typename ZT = XT> | |
struct SwJacobiPoint | |
{ | |
typedef _CurveT CurveT; | |
typedef SwJacobiPoint<CurveT,int,int,int> CanonicalSelfT; | |
XT x; | |
YT y; | |
ZT z; | |
/// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-madd-2007-bl | |
/// madd-2007-bl | |
/// Assumptions: Z2=1. | |
/// Source: 2007 Bernstein–Lange. | |
template<typename QT, IsAffineType<CanonicalSelfT,QT> = 0> | |
auto operator+( | |
const QT &Q | |
) { | |
const auto& X1 = this->x; | |
const auto& Y1 = this->y; | |
const auto& Z1 = this->z; | |
const auto& X2 = Q.x; | |
const auto& Y2 = Q.y; | |
const auto Z1Z1 = square(Z1); | |
const auto U2 = X2*Z1Z1; | |
const auto S2 = Y2*Z1*Z1Z1; | |
const auto H = U2-X1; | |
const auto HH = square(H); | |
const auto I = 4*HH; | |
const auto J = H*I; | |
const auto r = 2*(S2-Y1); | |
const auto V = X1*I; | |
const auto X3 = square(r)-J-2*V; | |
const auto Y3 = r*(V-X3)-2*Y1*J; | |
const auto Z3 = square(Z1+H)-Z1Z1-HH; | |
return SwJacobiPoint<CurveT,decltype(X3),decltype(Y3),decltype(Z3)> {X3, Y3, Z3}; | |
} | |
}; | |
template<typename _CurveT, typename XT, typename YT> | |
struct SwAffinePoint | |
{ | |
typedef _CurveT CurveT; | |
typedef SwAffinePoint<CurveT,int,int> CanonicalSelfT; | |
XT x; | |
YT y; | |
/// Add two affine points together, resulting in a jacobian point | |
/// mmadd-2007-bl | |
/// Assumptions: Z1=1 and Z2=1. | |
/// Source: 2007 Bernstein–Lange. | |
/// https://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#addition-add-2007-bl | |
template<typename QT, IsSamePointType<CanonicalSelfT,QT> = 0> | |
auto operator+( | |
const QT &Q | |
) { | |
const auto &X1 = this->x; | |
const auto &Y1 = this->y; | |
const auto &X2 = Q.x; | |
const auto &Y2 = Q.y; | |
require( X1 != X2 && Y1 != Y2 ); | |
const auto H = X2-X1; | |
const auto HH = square(H); | |
const auto I = 4*HH; | |
const auto J = H*I; | |
const auto r = 2*(Y2-Y1); | |
const auto V = X1*I; | |
const auto X3 = square(r)-J-2*V; | |
const auto Y3 = r*(V-X3)-2*Y1*J; | |
const auto Z3 = 2*H; | |
return SwJacobiPoint<CurveT,decltype(X3),decltype(Y3),decltype(Z3)> {X3, Y3, Z3}; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment