- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# eprecomp.cpp

    00001 // eprecomp.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004
    00005 // prevent Sun's CC compiler from including this file automatically
    00006 #if !defined(__SUNPRO_CC) || defined(CRYPTOPP_MANUALLY_INSTANTIATE_TEMPLATES)
    00007
    00008 #ifndef CRYPTOPP_IMPORTS
    00009
    00010 #include "eprecomp.h"
    00011 #include "asn.h"
    00012
    00013 NAMESPACE_BEGIN(CryptoPP)
    00014
    00015 template <class T> void DL_FixedBasePrecomputationImpl<T>::SetBase(const DL_GroupPrecomputation<Element> &group, const Element &i_base)
    00016 {
    00017         m_base = group.NeedConversions() ? group.ConvertIn(i_base) : i_base;
    00018
    00019         if (m_bases.empty() || !(m_base == m_bases[0]))
    00020         {
    00021                 m_bases.resize(1);
    00022                 m_bases[0] = m_base;
    00023         }
    00024
    00025         if (group.NeedConversions())
    00026                 m_base = i_base;
    00027 }
    00028
    00029 template <class T> void DL_FixedBasePrecomputationImpl<T>::Precompute(const DL_GroupPrecomputation<Element> &group, unsigned int maxExpBits, unsigned int storage)
    00030 {
    00031         assert(m_bases.size() > 0);
    00032         assert(storage <= maxExpBits);
    00033
    00034         if (storage > 1)
    00035         {
    00036                 m_windowSize = (maxExpBits+storage-1)/storage;
    00037                 m_exponentBase = Integer::Power2(m_windowSize);
    00038         }
    00039
    00040         m_bases.resize(storage);
    00041         for (unsigned i=1; i<storage; i++)
    00042                 m_bases[i] = group.GetGroup().ScalarMultiply(m_bases[i-1], m_exponentBase);
    00043 }
    00044
    00045 template <class T> void DL_FixedBasePrecomputationImpl<T>::Load(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt)
    00046 {
    00047         BERSequenceDecoder seq(bt);
    00048         word32 version;
    00049         BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1);
    00050         m_exponentBase.BERDecode(seq);
    00051         m_windowSize = m_exponentBase.BitCount() - 1;
    00052         m_bases.clear();
    00053         while (!seq.EndReached())
    00054                 m_bases.push_back(group.BERDecodeElement(seq));
    00055         if (!m_bases.empty() && group.NeedConversions())
    00056                 m_base = group.ConvertOut(m_bases[0]);
    00057         seq.MessageEnd();
    00058 }
    00059
    00060 template <class T> void DL_FixedBasePrecomputationImpl<T>::Save(const DL_GroupPrecomputation<Element> &group, BufferedTransformation &bt) const
    00061 {
    00062         DERSequenceEncoder seq(bt);
    00063         DEREncodeUnsigned<word32>(seq, 1);      // version
    00064         m_exponentBase.DEREncode(seq);
    00065         for (unsigned i=0; i<m_bases.size(); i++)
    00066                 group.DEREncodeElement(seq, m_bases[i]);
    00067         seq.MessageEnd();
    00068 }
    00069
    00070 template <class T> void DL_FixedBasePrecomputationImpl<T>::PrepareCascade(const DL_GroupPrecomputation<Element> &i_group, std::vector<BaseAndExponent<Element> > &eb, const Integer &exponent) const
    00071 {
    00072         const AbstractGroup<T> &group = i_group.GetGroup();
    00073
    00074         Integer r, q, e = exponent;
    00075         bool fastNegate = group.InversionIsFast() && m_windowSize > 1;
    00076         unsigned int i;
    00077
    00078         for (i=0; i+1<m_bases.size(); i++)
    00079         {
    00080                 Integer::DivideByPowerOf2(r, q, e, m_windowSize);
    00081                 std::swap(q, e);
    00082                 if (fastNegate && r.GetBit(m_windowSize-1))
    00083                 {
    00084                         ++e;
    00085                         eb.push_back(BaseAndExponent<Element>(group.Inverse(m_bases[i]), m_exponentBase - r));
    00086                 }
    00087                 else
    00088                         eb.push_back(BaseAndExponent<Element>(m_bases[i], r));
    00089         }
    00090         eb.push_back(BaseAndExponent<Element>(m_bases[i], e));
    00091 }
    00092
    00093 template <class T> T DL_FixedBasePrecomputationImpl<T>::Exponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent) const
    00094 {
    00095         std::vector<BaseAndExponent<Element> > eb;      // array of segments of the exponent and precalculated bases
    00096         eb.reserve(m_bases.size());
    00097         PrepareCascade(group, eb, exponent);
    00098         return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end()));
    00099 }
    00100
    00101 template <class T> T
    00102         DL_FixedBasePrecomputationImpl<T>::CascadeExponentiate(const DL_GroupPrecomputation<Element> &group, const Integer &exponent,
    00103                 const DL_FixedBasePrecomputation<T> &i_pc2, const Integer &exponent2) const
    00104 {
    00105         std::vector<BaseAndExponent<Element> > eb;      // array of segments of the exponent and precalculated bases
    00106         const DL_FixedBasePrecomputationImpl<T> &pc2 = static_cast<const DL_FixedBasePrecomputationImpl<T> &>(i_pc2);
    00107         eb.reserve(m_bases.size() + pc2.m_bases.size());
    00108         PrepareCascade(group, eb, exponent);
    00109         pc2.PrepareCascade(group, eb, exponent2);
    00110         return group.ConvertOut(GeneralCascadeMultiplication<Element>(group.GetGroup(), eb.begin(), eb.end()));
    00111 }
    00112
    00113 NAMESPACE_END
    00114
    00115 #endif
    00116
    00117 #endif