// eprecomp.cpp - originally written and placed in the public domain by Wei Dai #include "pch.h" #ifndef CRYPTOPP_IMPORTS #include "eprecomp.h" #include "integer.h" #include "algebra.h" #include "asn.h" NAMESPACE_BEGIN(CryptoPP) template void DL_FixedBasePrecomputationImpl::SetBase(const DL_GroupPrecomputation &group, const Element &i_base) { m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base; if (m_bases.empty() || !(m_base == m_bases[0])) { m_bases.resize(1); m_bases[0] = m_base; } if (group.NeedConversions()) m_base = i_base; } template void DL_FixedBasePrecomputationImpl::Precompute(const DL_GroupPrecomputation &group, unsigned int maxExpBits, unsigned int storage) { CRYPTOPP_ASSERT(m_bases.size() > 0); CRYPTOPP_ASSERT(storage <= maxExpBits); if (storage > 1) { m_windowSize = (maxExpBits+storage-1)/storage; m_exponentBase = Integer::Power2(m_windowSize); } m_bases.resize(storage); for (unsigned i=1; i void DL_FixedBasePrecomputationImpl::Load(const DL_GroupPrecomputation &group, BufferedTransformation &bt) { BERSequenceDecoder seq(bt); word32 version; BERDecodeUnsigned(seq, version, INTEGER, 1, 1); m_exponentBase.BERDecode(seq); m_windowSize = m_exponentBase.BitCount() - 1; m_bases.clear(); while (!seq.EndReached()) m_bases.push_back(group.BERDecodeElement(seq)); if (!m_bases.empty() && group.NeedConversions()) m_base = group.ConvertOut(m_bases[0]); seq.MessageEnd(); } template void DL_FixedBasePrecomputationImpl::Save(const DL_GroupPrecomputation &group, BufferedTransformation &bt) const { DERSequenceEncoder seq(bt); DEREncodeUnsigned(seq, 1); // version m_exponentBase.DEREncode(seq); for (unsigned i=0; i void DL_FixedBasePrecomputationImpl::PrepareCascade(const DL_GroupPrecomputation &i_group, std::vector > &eb, const Integer &exponent) const { const AbstractGroup &group = i_group.GetGroup(); Integer r, q, e = exponent; bool fastNegate = group.InversionIsFast() && m_windowSize > 1; unsigned int i; for (i=0; i+1(group.Inverse(m_bases[i]), m_exponentBase - r)); } else eb.push_back(BaseAndExponent(m_bases[i], r)); } eb.push_back(BaseAndExponent(m_bases[i], e)); } template T DL_FixedBasePrecomputationImpl::Exponentiate(const DL_GroupPrecomputation &group, const Integer &exponent) const { std::vector > eb; // array of segments of the exponent and precalculated bases eb.reserve(m_bases.size()); PrepareCascade(group, eb, exponent); return group.ConvertOut(GeneralCascadeMultiplication(group.GetGroup(), eb.begin(), eb.end())); } template T DL_FixedBasePrecomputationImpl::CascadeExponentiate(const DL_GroupPrecomputation &group, const Integer &exponent, const DL_FixedBasePrecomputation &i_pc2, const Integer &exponent2) const { std::vector > eb; // array of segments of the exponent and precalculated bases const DL_FixedBasePrecomputationImpl &pc2 = static_cast &>(i_pc2); eb.reserve(m_bases.size() + pc2.m_bases.size()); PrepareCascade(group, eb, exponent); pc2.PrepareCascade(group, eb, exponent2); return group.ConvertOut(GeneralCascadeMultiplication(group.GetGroup(), eb.begin(), eb.end())); } NAMESPACE_END #endif