00001 #include "pch.h"
00002 #include "eprecomp.h"
00003
00004 NAMESPACE_BEGIN(CryptoPP)
00005
00006 template <class T> void ExponentiationPrecomputation<T>::SetGroupAndBase(const Group &group, const Element &base)
00007 {
00008 m_group = &group;
00009 m_bases.resize(1);
00010 m_bases[0] = base;
00011 }
00012
00013 template <class T> void ExponentiationPrecomputation<T>::Precompute(unsigned int maxExpBits, unsigned int storage)
00014 {
00015 assert(m_group != NULL);
00016 assert(m_bases.size() > 0);
00017 assert(storage <= maxExpBits);
00018
00019 if (storage > 1)
00020 {
00021 m_windowSize = (maxExpBits+storage-1)/storage;
00022 m_exponentBase = Integer::Power2(m_windowSize);
00023 }
00024
00025 m_bases.resize(storage);
00026 for (unsigned i=1; i<storage; i++)
00027 m_bases[i] = m_group->ScalarMultiply(m_bases[i-1], m_exponentBase);
00028 }
00029
00030 template <class T> void ExponentiationPrecomputation<T>::PrepareCascade(std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const
00031 {
00032 Integer r, q, e = exponent;
00033 bool fastNegate = m_group->InversionIsFast() && m_windowSize > 1;
00034 unsigned int i;
00035
00036 for (i=0; i+1<m_bases.size(); i++)
00037 {
00038 Integer::DivideByPowerOf2(r, q, e, m_windowSize);
00039 std::swap(q, e);
00040 if (fastNegate && r.GetBit(m_windowSize-1))
00041 {
00042 ++e;
00043 eb.push_back(BaseAndExponent<Element>(m_group->Inverse(m_bases[i]), m_exponentBase - r));
00044 }
00045 else
00046 eb.push_back(BaseAndExponent<Element>(m_bases[i], r));
00047 }
00048 eb.push_back(BaseAndExponent<Element>(m_bases[i], e));
00049 }
00050
00051 template <class T> ExponentiationPrecomputation<T>::Element ExponentiationPrecomputation<T>::Exponentiate(const Integer &exponent) const
00052 {
00053 std::vector<BaseAndExponent<Element> > eb;
00054 eb.reserve(m_bases.size());
00055 PrepareCascade(eb, exponent);
00056 return GeneralCascadeMultiplication<Element>(*m_group, eb.begin(), eb.end());
00057 }
00058
00059 template <class T> T
00060 ExponentiationPrecomputation<T>::CascadeExponentiate(const Integer &exponent,
00061 const ExponentiationPrecomputation<T> &pc2, const Integer &exponent2) const
00062 {
00063 std::vector<BaseAndExponent<Element> > eb;
00064 eb.reserve(m_bases.size() + pc2.m_bases.size());
00065 PrepareCascade(eb, exponent);
00066 pc2.PrepareCascade(eb, exponent2);
00067 return GeneralCascadeMultiplication<Element>(*m_group, eb.begin(), eb.end());
00068 }
00069
00070 NAMESPACE_END