#ifndef _SECP256K1_ECMULT_ #define _SECP256K1_ECMULT_ #include #include #include "group.h" #include "scalar.h" namespace secp256k1 { template class WNAFPrecomp { private: G pre[1 << (W-2)]; public: WNAFPrecomp(const G &base) { pre[0] = base; GroupElemJac x = base; GroupElemJac d; d.SetDouble(x); for (int i=1; i<(1 << (W-2)); i++) { x.SetAdd(d,pre[i-1]); pre[i].SetJac(x); } } void Get(G &out, int exp) const { assert((exp & 1) == 1); assert(exp >= -((1 << (W-1)) - 1)); assert(exp <= ((1 << (W-1)) - 1)); if (exp > 0) { out = pre[(exp-1)/2]; } else { out.SetNeg(pre[(1-exp)/2]); } } }; template class WNAF { private: int naf[B+1]; int used; void PushNAF(int num, int zeroes) { for (int i=0; i wpg; ECMultConsts() : wpg(GetGroupConst().g) {} }; const ECMultConsts &GetECMultConsts() { static const ECMultConsts ecmult_consts; return ecmult_consts; } void ECMult(Context &ctx, GroupElemJac &out, GroupElemJac &a, Scalar &an, Scalar &gn) { WNAF<256> wa(ctx, an, 5); WNAF<256> wg(ctx, gn, 10); WNAFPrecomp wpa(a); const WNAFPrecomp &wpg = GetECMultConsts().wpg; int size = std::max(wa.GetSize(), wg.GetSize()); out = GroupElemJac(); GroupElemJac tmpj; GroupElem tmpa; for (int i=0; i