Skip to content

Instantly share code, notes, and snippets.

@HarryR
Created November 24, 2019 05:13
Show Gist options
  • Save HarryR/f1b74708622f394b9b7b7a34f61d5817 to your computer and use it in GitHub Desktop.
Save HarryR/f1b74708622f394b9b7b7a34f61d5817 to your computer and use it in GitHub Desktop.
/// 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