00001
00002
00003 #include "pch.h"
00004
00005
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);
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;
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;
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